@hexclave/next 1.0.14 → 1.0.15
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.
- package/dist/clickmap/clickmap-core.d.ts +15 -0
- package/dist/clickmap/clickmap-core.d.ts.map +1 -0
- package/dist/clickmap/clickmap-core.js +1527 -0
- package/dist/clickmap/clickmap-core.js.map +1 -0
- package/dist/clickmap/clickmap-styles.d.ts +5 -0
- package/dist/clickmap/clickmap-styles.d.ts.map +1 -0
- package/dist/clickmap/clickmap-styles.js +1095 -0
- package/dist/clickmap/clickmap-styles.js.map +1 -0
- package/dist/clickmap/index.d.ts +16 -0
- package/dist/clickmap/index.d.ts.map +1 -0
- package/dist/clickmap/index.js +74 -0
- package/dist/clickmap/index.js.map +1 -0
- package/dist/components/api-key-dialogs.js +5 -5
- package/dist/components/credential-sign-in.js +3 -3
- package/dist/components/credential-sign-up.js +5 -5
- package/dist/components/elements/sidebar-layout.js +1 -1
- package/dist/components/elements/user-avatar.js +1 -1
- package/dist/components/magic-link-sign-in.js +5 -5
- package/dist/components/message-cards/known-error-message-card.d.ts +1 -1
- package/dist/components/message-cards/predefined-message-card.js +1 -1
- package/dist/components/passkey-button.js +1 -1
- package/dist/components/profile-image-editor.js +1 -1
- package/dist/components/team-icon.js +1 -1
- package/dist/components/team-switcher.js +2 -2
- package/dist/components/user-button.js +1 -1
- package/dist/components-page/account-settings/active-sessions/active-sessions-page.js +1 -1
- package/dist/components-page/account-settings/editable-text.js +1 -1
- package/dist/components-page/account-settings/email-and-auth/emails-section.js +3 -3
- package/dist/components-page/account-settings/email-and-auth/mfa-section.js +1 -1
- package/dist/components-page/account-settings/email-and-auth/password-section.js +3 -3
- package/dist/components-page/account-settings/teams/team-api-keys-section.js +1 -1
- package/dist/components-page/account-settings/teams/team-creation-page.js +3 -3
- package/dist/components-page/account-settings/teams/team-member-invitation-section.js +4 -4
- package/dist/components-page/account-settings.js +3 -3
- package/dist/components-page/auth-page.js +2 -2
- package/dist/components-page/cli-auth-confirm.js +2 -2
- package/dist/components-page/cli-auth-confirm.test.js +1 -1
- package/dist/components-page/email-verification.js +1 -1
- package/dist/components-page/forgot-password.d.ts.map +1 -1
- package/dist/components-page/forgot-password.js +6 -7
- package/dist/components-page/forgot-password.js.map +1 -1
- package/dist/components-page/hexclave-handler-client.d.ts +1 -1
- package/dist/components-page/hexclave-handler-client.js +2 -2
- package/dist/components-page/magic-link-callback.js +1 -1
- package/dist/components-page/mfa.js +7 -22
- package/dist/components-page/mfa.js.map +1 -1
- package/dist/components-page/oauth-callback.js +2 -2
- package/dist/components-page/onboarding.js +4 -4
- package/dist/components-page/password-reset.d.ts.map +1 -1
- package/dist/components-page/password-reset.js +12 -14
- package/dist/components-page/password-reset.js.map +1 -1
- package/dist/components-page/team-creation.js +5 -5
- package/dist/dev-tool/dev-tool-core.d.ts.map +1 -1
- package/dist/dev-tool/dev-tool-core.js +258 -262
- package/dist/dev-tool/dev-tool-core.js.map +1 -1
- package/dist/dev-tool/dev-tool-styles.d.ts +1 -1
- package/dist/dev-tool/dev-tool-styles.d.ts.map +1 -1
- package/dist/dev-tool/dev-tool-styles.js +13 -143
- package/dist/dev-tool/dev-tool-styles.js.map +1 -1
- package/dist/dev-tool/index.d.ts.map +1 -1
- package/dist/dev-tool/index.js +4 -11
- package/dist/dev-tool/index.js.map +1 -1
- package/dist/esm/clickmap/clickmap-core.d.ts +15 -0
- package/dist/esm/clickmap/clickmap-core.d.ts.map +1 -0
- package/dist/esm/clickmap/clickmap-core.js +1525 -0
- package/dist/esm/clickmap/clickmap-core.js.map +1 -0
- package/dist/esm/clickmap/clickmap-styles.d.ts +5 -0
- package/dist/esm/clickmap/clickmap-styles.d.ts.map +1 -0
- package/dist/esm/clickmap/clickmap-styles.js +1093 -0
- package/dist/esm/clickmap/clickmap-styles.js.map +1 -0
- package/dist/esm/clickmap/index.d.ts +16 -0
- package/dist/esm/clickmap/index.d.ts.map +1 -0
- package/dist/esm/clickmap/index.js +72 -0
- package/dist/esm/clickmap/index.js.map +1 -0
- package/dist/esm/components/api-key-dialogs.js +5 -5
- package/dist/esm/components/credential-sign-in.js +3 -3
- package/dist/esm/components/credential-sign-up.js +5 -5
- package/dist/esm/components/elements/sidebar-layout.js +1 -1
- package/dist/esm/components/elements/user-avatar.js +1 -1
- package/dist/esm/components/magic-link-sign-in.js +5 -5
- package/dist/esm/components/message-cards/predefined-message-card.js +1 -1
- package/dist/esm/components/passkey-button.js +1 -1
- package/dist/esm/components/profile-image-editor.js +1 -1
- package/dist/esm/components/team-icon.js +1 -1
- package/dist/esm/components/team-switcher.js +2 -2
- package/dist/esm/components/user-button.js +1 -1
- package/dist/esm/components-page/account-settings/active-sessions/active-sessions-page.js +1 -1
- package/dist/esm/components-page/account-settings/editable-text.js +1 -1
- package/dist/esm/components-page/account-settings/email-and-auth/emails-section.js +3 -3
- package/dist/esm/components-page/account-settings/email-and-auth/mfa-section.js +1 -1
- package/dist/esm/components-page/account-settings/email-and-auth/password-section.js +3 -3
- package/dist/esm/components-page/account-settings/teams/team-api-keys-section.js +1 -1
- package/dist/esm/components-page/account-settings/teams/team-creation-page.js +3 -3
- package/dist/esm/components-page/account-settings/teams/team-member-invitation-section.js +4 -4
- package/dist/esm/components-page/account-settings.d.ts +1 -1
- package/dist/esm/components-page/account-settings.js +3 -3
- package/dist/esm/components-page/auth-page.js +2 -2
- package/dist/esm/components-page/cli-auth-confirm.js +2 -2
- package/dist/esm/components-page/cli-auth-confirm.test.js +1 -1
- package/dist/esm/components-page/email-verification.js +1 -1
- package/dist/esm/components-page/forgot-password.d.ts.map +1 -1
- package/dist/esm/components-page/forgot-password.js +6 -7
- package/dist/esm/components-page/forgot-password.js.map +1 -1
- package/dist/esm/components-page/hexclave-handler-client.d.ts +1 -1
- package/dist/esm/components-page/hexclave-handler-client.js +2 -2
- package/dist/esm/components-page/magic-link-callback.js +1 -1
- package/dist/esm/components-page/mfa.js +7 -22
- package/dist/esm/components-page/mfa.js.map +1 -1
- package/dist/esm/components-page/oauth-callback.js +2 -2
- package/dist/esm/components-page/onboarding.js +4 -4
- package/dist/esm/components-page/password-reset.d.ts.map +1 -1
- package/dist/esm/components-page/password-reset.js +11 -13
- package/dist/esm/components-page/password-reset.js.map +1 -1
- package/dist/esm/components-page/team-creation.js +5 -5
- package/dist/esm/dev-tool/dev-tool-core.d.ts.map +1 -1
- package/dist/esm/dev-tool/dev-tool-core.js +35 -39
- package/dist/esm/dev-tool/dev-tool-core.js.map +1 -1
- package/dist/esm/dev-tool/dev-tool-styles.d.ts +1 -1
- package/dist/esm/dev-tool/dev-tool-styles.d.ts.map +1 -1
- package/dist/esm/dev-tool/dev-tool-styles.js +13 -143
- package/dist/esm/dev-tool/dev-tool-styles.js.map +1 -1
- package/dist/esm/dev-tool/index.d.ts.map +1 -1
- package/dist/esm/dev-tool/index.js +1 -8
- package/dist/esm/dev-tool/index.js.map +1 -1
- package/dist/esm/generated/global-css.d.ts +1 -1
- package/dist/esm/generated/global-css.js +1 -1
- package/dist/esm/generated/global-css.js.map +1 -1
- package/dist/esm/generated/quetzal-translations.d.ts +2 -2
- package/dist/esm/in-page-ui/base-styles.d.ts +5 -0
- package/dist/esm/in-page-ui/base-styles.d.ts.map +1 -0
- package/dist/esm/in-page-ui/base-styles.js +166 -0
- package/dist/esm/in-page-ui/base-styles.js.map +1 -0
- package/dist/esm/in-page-ui/dom.d.ts +15 -0
- package/dist/esm/in-page-ui/dom.d.ts.map +1 -0
- package/dist/esm/in-page-ui/dom.js +44 -0
- package/dist/esm/in-page-ui/dom.js.map +1 -0
- package/dist/esm/lib/auth.js +2 -2
- package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +6 -2
- package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.js +21 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js +4 -2
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/common.js +2 -2
- package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.d.ts +13 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.js +146 -14
- package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.test.js +221 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.test.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.js +1 -1
- package/dist/esm/lib/hexclave-app/apps/interfaces/admin-app.d.ts +5 -0
- package/dist/esm/lib/hexclave-app/apps/interfaces/admin-app.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/interfaces/admin-app.js.map +1 -1
- package/dist/esm/lib/hexclave-app/users/index.d.ts +1 -1
- package/dist/esm/providers/theme-provider.js +1 -1
- package/dist/esm/providers/translation-provider.js +1 -1
- package/dist/generated/global-css.d.ts +1 -1
- package/dist/generated/global-css.js +1 -1
- package/dist/generated/global-css.js.map +1 -1
- package/dist/generated/quetzal-translations.d.ts +2 -2
- package/dist/in-page-ui/base-styles.d.ts +5 -0
- package/dist/in-page-ui/base-styles.d.ts.map +1 -0
- package/dist/in-page-ui/base-styles.js +168 -0
- package/dist/in-page-ui/base-styles.js.map +1 -0
- package/dist/in-page-ui/dom.d.ts +15 -0
- package/dist/in-page-ui/dom.d.ts.map +1 -0
- package/dist/in-page-ui/dom.js +51 -0
- package/dist/in-page-ui/dom.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/integrations/convex/component/convex.config.d.ts +1 -1
- package/dist/lib/auth.js +2 -2
- package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +5 -1
- package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.js +21 -1
- package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js +4 -2
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/common.js +2 -2
- package/dist/lib/hexclave-app/apps/implementations/event-tracker.d.ts +13 -0
- package/dist/lib/hexclave-app/apps/implementations/event-tracker.d.ts.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/event-tracker.js +146 -14
- package/dist/lib/hexclave-app/apps/implementations/event-tracker.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/event-tracker.test.js +221 -0
- package/dist/lib/hexclave-app/apps/implementations/event-tracker.test.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/server-app-impl.js +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/admin-app.d.ts +5 -0
- package/dist/lib/hexclave-app/apps/interfaces/admin-app.d.ts.map +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/admin-app.js.map +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/server-app.d.ts +1 -1
- package/dist/lib/hexclave-app/common.d.ts +1 -1
- package/dist/providers/hexclave-provider-client.d.ts +1 -1
- package/dist/providers/theme-provider.js +1 -1
- package/dist/providers/translation-provider.js +1 -1
- package/dist/{storage-CKzvsBxG.d.ts → storage-ksajV_p6.d.ts} +1 -1
- package/dist/{storage-CKzvsBxG.d.ts.map → storage-ksajV_p6.d.ts.map} +1 -1
- package/package.json +4 -4
- package/src/clickmap/clickmap-core.ts +1997 -0
- package/src/clickmap/clickmap-styles.ts +1102 -0
- package/src/clickmap/index.ts +95 -0
- package/src/components-page/forgot-password.tsx +1 -2
- package/src/components-page/mfa.tsx +12 -21
- package/src/components-page/password-reset.tsx +4 -6
- package/src/dev-tool/dev-tool-core.ts +38 -65
- package/src/dev-tool/dev-tool-styles.ts +13 -142
- package/src/dev-tool/index.ts +1 -14
- package/src/in-page-ui/base-styles.ts +171 -0
- package/src/in-page-ui/dom.ts +80 -0
- package/src/lib/hexclave-app/apps/implementations/admin-app-impl.ts +23 -1
- package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +7 -0
- package/src/lib/hexclave-app/apps/implementations/event-tracker.test.ts +287 -0
- package/src/lib/hexclave-app/apps/implementations/event-tracker.ts +226 -16
- package/src/lib/hexclave-app/apps/interfaces/admin-app.ts +3 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
|
|
2
|
+
//===========================================
|
|
3
|
+
// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template
|
|
4
|
+
//===========================================
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
CLICKMAP_OVERLAY_RESUME_STORAGE_KEY,
|
|
8
|
+
CLICKMAP_OVERLAY_TOKEN_UPDATED_EVENT,
|
|
9
|
+
} from "@hexclave/shared/dist/utils/analytics-clickmap-overlay";
|
|
10
|
+
import { captureError } from "@hexclave/shared/dist/utils/errors";
|
|
11
|
+
import { runAsynchronously } from "@hexclave/shared/dist/utils/promises";
|
|
12
|
+
import { canMountIntoDom } from "../in-page-ui/dom";
|
|
13
|
+
import type { StackClientApp } from "../lib/hexclave-app";
|
|
14
|
+
import type { openClickmapOverlay as OpenClickmapOverlayFn } from "./clickmap-core";
|
|
15
|
+
|
|
16
|
+
// While the overlay is open it drops a sentinel into sessionStorage on unload
|
|
17
|
+
// (see clickmap-core); consuming it here reopens the clickmap on the next page
|
|
18
|
+
// so the user picks up where they left off.
|
|
19
|
+
function consumeResumeSentinel(): boolean {
|
|
20
|
+
try {
|
|
21
|
+
if (sessionStorage.getItem(CLICKMAP_OVERLAY_RESUME_STORAGE_KEY) !== '1') return false;
|
|
22
|
+
sessionStorage.removeItem(CLICKMAP_OVERLAY_RESUME_STORAGE_KEY);
|
|
23
|
+
return true;
|
|
24
|
+
} catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let activeApp: StackClientApp<true> | null = null;
|
|
30
|
+
let activeOverlayCleanup: (() => void) | null = null;
|
|
31
|
+
let openGeneration = 0;
|
|
32
|
+
let tokenListenerAttached = false;
|
|
33
|
+
|
|
34
|
+
let openClickmapOverlayPromise: Promise<typeof OpenClickmapOverlayFn> | null = null;
|
|
35
|
+
function loadOpenClickmapOverlay(): Promise<typeof OpenClickmapOverlayFn> {
|
|
36
|
+
if (!openClickmapOverlayPromise) {
|
|
37
|
+
openClickmapOverlayPromise = import("./clickmap-core").then(m => m.openClickmapOverlay).catch((err) => {
|
|
38
|
+
openClickmapOverlayPromise = null;
|
|
39
|
+
throw err;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return openClickmapOverlayPromise;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function tryOpenOverlay() {
|
|
46
|
+
// Already open: the panel listens for the token event itself and refetches.
|
|
47
|
+
if (activeOverlayCleanup || !activeApp || !canMountIntoDom()) return;
|
|
48
|
+
|
|
49
|
+
const generation = ++openGeneration;
|
|
50
|
+
const app = activeApp;
|
|
51
|
+
|
|
52
|
+
runAsynchronously(async () => {
|
|
53
|
+
const openClickmapOverlay = await loadOpenClickmapOverlay();
|
|
54
|
+
if (generation !== openGeneration) return;
|
|
55
|
+
if (activeOverlayCleanup || activeApp !== app || !canMountIntoDom()) return;
|
|
56
|
+
activeOverlayCleanup = openClickmapOverlay(app, () => {
|
|
57
|
+
activeOverlayCleanup = null;
|
|
58
|
+
});
|
|
59
|
+
}, {
|
|
60
|
+
noErrorLogging: true,
|
|
61
|
+
onError: (error) => {
|
|
62
|
+
captureError("clickmap-mount", error);
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Mounts the clickmap overlay listener on the page.
|
|
69
|
+
*
|
|
70
|
+
* The clickmap is fully independent from the dev tool. It has no ambient UI:
|
|
71
|
+
* nothing renders until a dashboard-minted token is handed over (the
|
|
72
|
+
* CLICKMAP_OVERLAY_TOKEN_UPDATED event fired by the dashboard's console
|
|
73
|
+
* snippet) or a navigation-resume sentinel is present — only then is the
|
|
74
|
+
* actual overlay code lazily loaded and shown.
|
|
75
|
+
*/
|
|
76
|
+
export function mountClickmapOverlay(app: StackClientApp<true>): () => void {
|
|
77
|
+
activeApp = app;
|
|
78
|
+
|
|
79
|
+
if (typeof window !== 'undefined' && !tokenListenerAttached) {
|
|
80
|
+
tokenListenerAttached = true;
|
|
81
|
+
window.addEventListener(CLICKMAP_OVERLAY_TOKEN_UPDATED_EVENT, tryOpenOverlay);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (canMountIntoDom() && consumeResumeSentinel()) {
|
|
85
|
+
tryOpenOverlay();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return () => {
|
|
89
|
+
if (activeApp !== app) return;
|
|
90
|
+
activeApp = null;
|
|
91
|
+
openGeneration++;
|
|
92
|
+
activeOverlayCleanup?.();
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
@@ -54,8 +54,7 @@ export function ForgotPasswordForm({ onSent }: { onSent?: () => void }) {
|
|
|
54
54
|
id="email"
|
|
55
55
|
type="email"
|
|
56
56
|
autoComplete="email"
|
|
57
|
-
{...register('email')}
|
|
58
|
-
onChange={() => clearErrors('email')}
|
|
57
|
+
{...register('email', { onChange: () => clearErrors('email') })}
|
|
59
58
|
/>
|
|
60
59
|
<FormWarningText text={errors.email?.message?.toString()} />
|
|
61
60
|
|
|
@@ -196,27 +196,18 @@ export function MFA(props: {
|
|
|
196
196
|
const headerText = t("Multi-Factor Authentication");
|
|
197
197
|
const instructionText = t("Enter the six-digit code from your authenticator app");
|
|
198
198
|
|
|
199
|
-
if (props.fullPage) {
|
|
200
|
-
return (
|
|
201
|
-
<MaybeFullPage fullPage={true}>
|
|
202
|
-
<div
|
|
203
|
-
className="stack-scope flex flex-col items-stretch"
|
|
204
|
-
style={{ maxWidth: "380px", flexBasis: "380px", padding: "1rem" }}
|
|
205
|
-
>
|
|
206
|
-
<div className="text-center mb-6">
|
|
207
|
-
<Typography type="h2">{headerText}</Typography>
|
|
208
|
-
<Typography className="mt-2">{instructionText}</Typography>
|
|
209
|
-
</div>
|
|
210
|
-
<MfaForm onSuccess={props.onSuccess} onCancel={props.onCancel} />
|
|
211
|
-
</div>
|
|
212
|
-
</MaybeFullPage>
|
|
213
|
-
);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
199
|
return (
|
|
217
|
-
<
|
|
218
|
-
<
|
|
219
|
-
|
|
220
|
-
|
|
200
|
+
<MaybeFullPage fullPage={!!props.fullPage}>
|
|
201
|
+
<div className={cn(
|
|
202
|
+
"stack-scope max-w-[380px] flex-basis-[380px]",
|
|
203
|
+
props.fullPage ? "p-4" : "p-0"
|
|
204
|
+
)}>
|
|
205
|
+
<div className="text-center mb-6">
|
|
206
|
+
<Typography type="h2">{headerText}</Typography>
|
|
207
|
+
<Typography className="mt-2 text-sm text-muted-foreground">{instructionText}</Typography>
|
|
208
|
+
</div>
|
|
209
|
+
<MfaForm onSuccess={props.onSuccess} onCancel={props.onCancel} />
|
|
210
|
+
</div>
|
|
211
|
+
</MaybeFullPage>
|
|
221
212
|
);
|
|
222
213
|
}
|
|
@@ -100,11 +100,10 @@ export default function PasswordResetForm(props: {
|
|
|
100
100
|
<PasswordInput
|
|
101
101
|
id="password"
|
|
102
102
|
autoComplete="new-password"
|
|
103
|
-
{...register('password')
|
|
104
|
-
onChange={() => {
|
|
103
|
+
{...register('password', { onChange: () => {
|
|
105
104
|
clearErrors('password');
|
|
106
105
|
clearErrors('passwordRepeat');
|
|
107
|
-
}}
|
|
106
|
+
} })}
|
|
108
107
|
/>
|
|
109
108
|
<FormWarningText text={errors.password?.message?.toString()} />
|
|
110
109
|
|
|
@@ -112,11 +111,10 @@ export default function PasswordResetForm(props: {
|
|
|
112
111
|
<PasswordInput
|
|
113
112
|
id="repeat-password"
|
|
114
113
|
autoComplete="new-password"
|
|
115
|
-
{...register('passwordRepeat')
|
|
116
|
-
onChange={() => {
|
|
114
|
+
{...register('passwordRepeat', { onChange: () => {
|
|
117
115
|
clearErrors('password');
|
|
118
116
|
clearErrors('passwordRepeat');
|
|
119
|
-
}}
|
|
117
|
+
} })}
|
|
120
118
|
/>
|
|
121
119
|
<FormWarningText text={errors.passwordRepeat?.message?.toString()} />
|
|
122
120
|
|
|
@@ -4,10 +4,12 @@
|
|
|
4
4
|
//===========================================
|
|
5
5
|
|
|
6
6
|
import type { RequestLogEntry } from "@hexclave/shared/dist/interface/client-interface";
|
|
7
|
+
import { DEV_TOOL_ROOT_ID } from "@hexclave/shared/dist/utils/dev-tool";
|
|
7
8
|
import { runAsynchronously } from "@hexclave/shared/dist/utils/promises";
|
|
8
9
|
import { isLocalhost } from "@hexclave/shared/dist/utils/urls";
|
|
9
10
|
import type { StackClientApp } from "../lib/hexclave-app";
|
|
10
11
|
import { envVars } from "../generated/env";
|
|
12
|
+
import { getGlobalUiInstance, h, hasAppendChild, setGlobalUiInstance, setHtml, type UiGlobalInstance } from "../in-page-ui/dom";
|
|
11
13
|
import { getBaseUrl } from "../lib/hexclave-app/apps/implementations/common";
|
|
12
14
|
import type { HandlerUrlOptions, HandlerUrls, HandlerUrlTarget } from "../lib/hexclave-app/common";
|
|
13
15
|
import { hexclaveAppInternalsSymbol } from "../lib/hexclave-app/common";
|
|
@@ -55,7 +57,7 @@ type DevToolState = {
|
|
|
55
57
|
// Hexclave rebrand: UI-only local prefs — straight rename (one-time reset is harmless)
|
|
56
58
|
const STORAGE_KEY = '__hexclave-dev-tool-state';
|
|
57
59
|
const TRIGGER_POS_KEY = 'hexclave-devtool-trigger-position';
|
|
58
|
-
const ROOT_ID =
|
|
60
|
+
const ROOT_ID = DEV_TOOL_ROOT_ID;
|
|
59
61
|
const GLOBAL_INSTANCE_KEY = '__hexclave-dev-tool-instance';
|
|
60
62
|
const MAX_LOG_ENTRIES = 500;
|
|
61
63
|
const CONSOLE_LOG_BATCH_SIZE = 100;
|
|
@@ -71,6 +73,10 @@ const TABS: { id: TabId; label: string; icon: string }[] = [
|
|
|
71
73
|
{ id: 'support', label: 'Support', icon: '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>' },
|
|
72
74
|
];
|
|
73
75
|
|
|
76
|
+
// Clickmaps is intentionally NOT a dev tool tab or feature. It's a fully
|
|
77
|
+
// independent module (see src/clickmap) with its own mount, root element, and
|
|
78
|
+
// styles, so the dev tool can be changed or removed without affecting it.
|
|
79
|
+
|
|
74
80
|
const DEFAULT_STATE: DevToolState = {
|
|
75
81
|
isOpen: false,
|
|
76
82
|
activeTab: 'overview',
|
|
@@ -142,29 +148,6 @@ type LogStore = {
|
|
|
142
148
|
subscribe(fn: () => void): () => void;
|
|
143
149
|
};
|
|
144
150
|
|
|
145
|
-
type DevToolGlobalInstance = {
|
|
146
|
-
cleanup: () => void;
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
function isDevToolGlobalInstance(value: unknown): value is DevToolGlobalInstance {
|
|
150
|
-
return typeof value === 'object' && value !== null && typeof Reflect.get(value, 'cleanup') === 'function';
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
function getGlobalDevToolInstance(): DevToolGlobalInstance | null {
|
|
154
|
-
if (typeof window === 'undefined') return null;
|
|
155
|
-
const value: unknown = Reflect.get(window, GLOBAL_INSTANCE_KEY);
|
|
156
|
-
return isDevToolGlobalInstance(value) ? value : null;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
function setGlobalDevToolInstance(instance: DevToolGlobalInstance | null) {
|
|
160
|
-
if (typeof window === 'undefined') return;
|
|
161
|
-
if (instance === null) {
|
|
162
|
-
Reflect.deleteProperty(window, GLOBAL_INSTANCE_KEY);
|
|
163
|
-
} else {
|
|
164
|
-
Reflect.set(window, GLOBAL_INSTANCE_KEY, instance);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
151
|
function getGlobalLogStore(): LogStore {
|
|
169
152
|
const g = globalThis as any;
|
|
170
153
|
if (!g.__STACK_DEV_TOOL_LOG_STORE__) {
|
|
@@ -272,41 +255,6 @@ function generateRandomEmail(): string {
|
|
|
272
255
|
// DOM helpers
|
|
273
256
|
// ---------------------------------------------------------------------------
|
|
274
257
|
|
|
275
|
-
function h<K extends keyof HTMLElementTagNameMap>(
|
|
276
|
-
tag: K,
|
|
277
|
-
attrs?: Record<string, any> | null,
|
|
278
|
-
...children: (string | Node | null | undefined)[]
|
|
279
|
-
): HTMLElementTagNameMap[K] {
|
|
280
|
-
const el = document.createElement(tag);
|
|
281
|
-
if (attrs) {
|
|
282
|
-
for (const [k, v] of Object.entries(attrs)) {
|
|
283
|
-
if (v == null) continue;
|
|
284
|
-
if (k === 'className') {
|
|
285
|
-
el.className = v;
|
|
286
|
-
} else if (k === 'style' && typeof v === 'object') {
|
|
287
|
-
Object.assign(el.style, v);
|
|
288
|
-
} else if (k.startsWith('on') && typeof v === 'function') {
|
|
289
|
-
el.addEventListener(k.slice(2).toLowerCase(), v);
|
|
290
|
-
} else {
|
|
291
|
-
el.setAttribute(k, String(v));
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
for (const child of children) {
|
|
296
|
-
if (child == null) continue;
|
|
297
|
-
el.appendChild(typeof child === 'string' ? document.createTextNode(child) : child);
|
|
298
|
-
}
|
|
299
|
-
return el;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
function setHtml(el: HTMLElement, html: string) {
|
|
303
|
-
el.innerHTML = html;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
function hasAppendChild(value: unknown): value is { appendChild(node: Node): void } {
|
|
307
|
-
return typeof value === 'object' && value !== null && typeof Reflect.get(value, 'appendChild') === 'function';
|
|
308
|
-
}
|
|
309
|
-
|
|
310
258
|
function parseMarkdownImage(line: string): { alt: string, src: string } | null {
|
|
311
259
|
const match = line.trim().match(/^!\[([^\]]*)\]\((.+)\)$/);
|
|
312
260
|
if (!match) return null;
|
|
@@ -666,8 +614,13 @@ function createIframeTab(src: string, title: string, loadingMsg = 'Loading\u2026
|
|
|
666
614
|
// Overview tab
|
|
667
615
|
// ---------------------------------------------------------------------------
|
|
668
616
|
|
|
617
|
+
function hasPersistentTokenStoreForDevTool(app: StackClientApp<boolean>): boolean {
|
|
618
|
+
return app[hexclaveAppInternalsSymbol].getConstructorOptions().tokenStore !== null;
|
|
619
|
+
}
|
|
620
|
+
|
|
669
621
|
function createOverviewTab(app: StackClientApp<true>): TabResult {
|
|
670
622
|
const container = h('div', { className: 'sdt-ov' });
|
|
623
|
+
const hasPersistentTokenStore = hasPersistentTokenStoreForDevTool(app);
|
|
671
624
|
|
|
672
625
|
// ── Identity card ──────────────────────────────────────────────────────────
|
|
673
626
|
const heroCard = h('div', { className: 'sdt-ov-card sdt-ov-card-hero' });
|
|
@@ -721,6 +674,12 @@ function createOverviewTab(app: StackClientApp<true>): TabResult {
|
|
|
721
674
|
|
|
722
675
|
function rebuildActions() {
|
|
723
676
|
actions.innerHTML = '';
|
|
677
|
+
if (!hasPersistentTokenStore) {
|
|
678
|
+
userName.textContent = 'Current user unavailable';
|
|
679
|
+
userEmail.textContent = 'This app was initialized without a token store';
|
|
680
|
+
actions.appendChild(h('button', { className: 'sdt-ov-btn sdt-ov-btn-wide', disabled: 'true' }, 'Session actions unavailable'));
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
724
683
|
if (currentUser) {
|
|
725
684
|
const signOutBtn = h('button', { className: 'sdt-ov-btn sdt-ov-btn-danger' }, 'Sign Out');
|
|
726
685
|
signOutBtn.disabled = loading;
|
|
@@ -895,10 +854,13 @@ function createOverviewTab(app: StackClientApp<true>): TabResult {
|
|
|
895
854
|
|
|
896
855
|
function buildChecklist() {
|
|
897
856
|
checksCard.innerHTML = '';
|
|
857
|
+
const currentUserCheck = hasPersistentTokenStore
|
|
858
|
+
? { ok: !!currentUser, label: 'Sign in a test user', hint: 'Use \u201cQuick Sign In\u201d above \u2192' }
|
|
859
|
+
: { ok: true, label: 'Current-user tools unavailable', hint: null };
|
|
898
860
|
const checks = [
|
|
899
861
|
{ ok: !!projectId && projectId !== 'default', label: 'Project configured', hint: null },
|
|
900
862
|
{ ok: hasActiveAuthMethod === true, label: 'Auth method active', hint: hasActiveAuthMethod === null ? 'Still checking project config' : null },
|
|
901
|
-
|
|
863
|
+
currentUserCheck,
|
|
902
864
|
];
|
|
903
865
|
const passCount = checks.filter((c) => c.ok).length;
|
|
904
866
|
const allGood = passCount === checks.length;
|
|
@@ -940,6 +902,17 @@ function createOverviewTab(app: StackClientApp<true>): TabResult {
|
|
|
940
902
|
}
|
|
941
903
|
|
|
942
904
|
async function refreshUser() {
|
|
905
|
+
if (!hasPersistentTokenStore) {
|
|
906
|
+
avatar.className = 'sdt-ov-avatar';
|
|
907
|
+
avatar.textContent = '?';
|
|
908
|
+
userName.textContent = 'Current user unavailable';
|
|
909
|
+
userEmail.textContent = 'This app was initialized without a token store';
|
|
910
|
+
authIndicator.style.display = 'none';
|
|
911
|
+
currentUser = null;
|
|
912
|
+
rebuildActions();
|
|
913
|
+
buildChecklist();
|
|
914
|
+
return;
|
|
915
|
+
}
|
|
943
916
|
try {
|
|
944
917
|
currentUser = await app.getUser();
|
|
945
918
|
|
|
@@ -2354,7 +2327,7 @@ export function createDevTool(app: StackClientApp<true>): () => void {
|
|
|
2354
2327
|
const body = Reflect.get(document, 'body');
|
|
2355
2328
|
if (!hasAppendChild(body)) return () => {};
|
|
2356
2329
|
|
|
2357
|
-
|
|
2330
|
+
getGlobalUiInstance(GLOBAL_INSTANCE_KEY)?.cleanup();
|
|
2358
2331
|
let existingRoot = document.getElementById(ROOT_ID);
|
|
2359
2332
|
while (existingRoot !== null) {
|
|
2360
2333
|
existingRoot.remove();
|
|
@@ -2436,12 +2409,12 @@ export function createDevTool(app: StackClientApp<true>): () => void {
|
|
|
2436
2409
|
});
|
|
2437
2410
|
|
|
2438
2411
|
let didCleanup = false;
|
|
2439
|
-
const instance:
|
|
2412
|
+
const instance: UiGlobalInstance = {
|
|
2440
2413
|
cleanup: () => {
|
|
2441
2414
|
if (didCleanup) return;
|
|
2442
2415
|
didCleanup = true;
|
|
2443
|
-
if (
|
|
2444
|
-
|
|
2416
|
+
if (getGlobalUiInstance(GLOBAL_INSTANCE_KEY) === instance) {
|
|
2417
|
+
setGlobalUiInstance(GLOBAL_INSTANCE_KEY, null);
|
|
2445
2418
|
}
|
|
2446
2419
|
trigger.cleanup();
|
|
2447
2420
|
removeRequestListener();
|
|
@@ -2451,7 +2424,7 @@ export function createDevTool(app: StackClientApp<true>): () => void {
|
|
|
2451
2424
|
}
|
|
2452
2425
|
},
|
|
2453
2426
|
};
|
|
2454
|
-
|
|
2427
|
+
setGlobalUiInstance(GLOBAL_INSTANCE_KEY, instance);
|
|
2455
2428
|
|
|
2456
2429
|
return () => {
|
|
2457
2430
|
instance.cleanup();
|
|
@@ -5,53 +5,11 @@
|
|
|
5
5
|
// Theme-aware CSS for the dev tool indicator
|
|
6
6
|
// Respects Stack theme (data-stack-theme attribute) and system prefers-color-scheme
|
|
7
7
|
// Uses .hexclave-devtool scope to avoid conflicts with host app styles
|
|
8
|
+
// Design tokens + base reset come from the shared in-page-ui module.
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
.hexclave-devtool {
|
|
11
|
-
--sdt-bg: #0a0a0b;
|
|
12
|
-
--sdt-bg-elevated: #141416;
|
|
13
|
-
--sdt-bg-hover: #1c1c1f;
|
|
14
|
-
--sdt-bg-active: #232326;
|
|
15
|
-
--sdt-bg-subtle: #111113;
|
|
16
|
-
--sdt-border: #2a2a2e;
|
|
17
|
-
--sdt-border-subtle: #1e1e22;
|
|
18
|
-
--sdt-text: #ececef;
|
|
19
|
-
--sdt-text-secondary: #8b8b93;
|
|
20
|
-
--sdt-text-tertiary: #5c5c66;
|
|
21
|
-
--sdt-accent: #6366f1;
|
|
22
|
-
--sdt-accent-hover: #818cf8;
|
|
23
|
-
--sdt-accent-muted: rgba(99, 102, 241, 0.15);
|
|
24
|
-
--sdt-success: #22c55e;
|
|
25
|
-
--sdt-success-muted: rgba(34, 197, 94, 0.15);
|
|
26
|
-
--sdt-warning: #eab308;
|
|
27
|
-
--sdt-warning-muted: rgba(234, 179, 8, 0.15);
|
|
28
|
-
--sdt-error: #ef4444;
|
|
29
|
-
--sdt-error-muted: rgba(239, 68, 68, 0.15);
|
|
30
|
-
--sdt-info: #3b82f6;
|
|
31
|
-
--sdt-info-muted: rgba(59, 130, 246, 0.15);
|
|
32
|
-
--sdt-overlay-bg: rgba(17, 17, 19, 0.92);
|
|
33
|
-
--sdt-radius: 8px;
|
|
34
|
-
--sdt-radius-sm: 4px;
|
|
35
|
-
--sdt-radius-lg: 12px;
|
|
36
|
-
--sdt-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
37
|
-
--sdt-font-mono: 'SF Mono', SFMono-Regular, ui-monospace, 'DejaVu Sans Mono', Menlo, Consolas, monospace;
|
|
38
|
-
--sdt-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.05);
|
|
39
|
-
--sdt-trigger-shadow: 0 4px 12px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.08);
|
|
40
|
-
|
|
41
|
-
all: initial;
|
|
42
|
-
font-family: var(--sdt-font);
|
|
43
|
-
color: var(--sdt-text);
|
|
44
|
-
font-size: 13px;
|
|
45
|
-
line-height: 1.5;
|
|
46
|
-
-webkit-font-smoothing: antialiased;
|
|
47
|
-
-moz-osx-font-smoothing: grayscale;
|
|
48
|
-
box-sizing: border-box;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
.hexclave-devtool *, .hexclave-devtool *::before, .hexclave-devtool *::after {
|
|
52
|
-
box-sizing: border-box;
|
|
53
|
-
}
|
|
10
|
+
import { getInPageUiBaseCSS } from "../in-page-ui/base-styles";
|
|
54
11
|
|
|
12
|
+
export const devToolCSS = getInPageUiBaseCSS('.hexclave-devtool') + `
|
|
55
13
|
/* Trigger pill */
|
|
56
14
|
.hexclave-devtool .sdt-trigger {
|
|
57
15
|
position: fixed;
|
|
@@ -103,7 +61,7 @@ export const devToolCSS = `
|
|
|
103
61
|
position: fixed;
|
|
104
62
|
bottom: 60px;
|
|
105
63
|
right: 16px;
|
|
106
|
-
z-index:
|
|
64
|
+
z-index: 2147483647;
|
|
107
65
|
width: 800px;
|
|
108
66
|
max-width: calc(100vw - 32px);
|
|
109
67
|
height: 520px;
|
|
@@ -193,6 +151,7 @@ export const devToolCSS = `
|
|
|
193
151
|
flex-shrink: 0;
|
|
194
152
|
gap: 2px;
|
|
195
153
|
overflow-x: auto;
|
|
154
|
+
overflow-y: hidden;
|
|
196
155
|
}
|
|
197
156
|
|
|
198
157
|
.hexclave-devtool .sdt-panel-fullscreen .sdt-tabbar {
|
|
@@ -263,9 +222,15 @@ export const devToolCSS = `
|
|
|
263
222
|
}
|
|
264
223
|
|
|
265
224
|
.hexclave-devtool .sdt-tabbar-actions {
|
|
225
|
+
position: sticky;
|
|
226
|
+
right: 0;
|
|
227
|
+
z-index: 2;
|
|
266
228
|
display: flex;
|
|
267
229
|
align-items: center;
|
|
230
|
+
align-self: stretch;
|
|
268
231
|
gap: 4px;
|
|
232
|
+
padding-left: 6px;
|
|
233
|
+
background: inherit;
|
|
269
234
|
flex-shrink: 0;
|
|
270
235
|
}
|
|
271
236
|
|
|
@@ -370,19 +335,6 @@ export const devToolCSS = `
|
|
|
370
335
|
}
|
|
371
336
|
}
|
|
372
337
|
|
|
373
|
-
.hexclave-devtool .sdt-tab-pane::-webkit-scrollbar {
|
|
374
|
-
width: 6px;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
.hexclave-devtool .sdt-tab-pane::-webkit-scrollbar-track {
|
|
378
|
-
background: transparent;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
.hexclave-devtool .sdt-tab-pane::-webkit-scrollbar-thumb {
|
|
382
|
-
background: var(--sdt-border);
|
|
383
|
-
border-radius: 3px;
|
|
384
|
-
}
|
|
385
|
-
|
|
386
338
|
/* ===== Overview tab — single column ===== */
|
|
387
339
|
|
|
388
340
|
.hexclave-devtool .sdt-ov {
|
|
@@ -1935,35 +1887,8 @@ export const devToolCSS = `
|
|
|
1935
1887
|
opacity: 1;
|
|
1936
1888
|
}
|
|
1937
1889
|
|
|
1938
|
-
/*
|
|
1939
|
-
|
|
1940
|
-
.hexclave-devtool {
|
|
1941
|
-
--sdt-bg: #ffffff;
|
|
1942
|
-
--sdt-bg-elevated: #f8f8fa;
|
|
1943
|
-
--sdt-bg-hover: #f0f0f3;
|
|
1944
|
-
--sdt-bg-active: #e8e8ec;
|
|
1945
|
-
--sdt-bg-subtle: #fafafa;
|
|
1946
|
-
--sdt-border: #e0e0e5;
|
|
1947
|
-
--sdt-border-subtle: #eaeaef;
|
|
1948
|
-
--sdt-text: #111113;
|
|
1949
|
-
--sdt-text-secondary: #6b6b73;
|
|
1950
|
-
--sdt-text-tertiary: #9b9ba3;
|
|
1951
|
-
--sdt-accent: #6366f1;
|
|
1952
|
-
--sdt-accent-hover: #4f46e5;
|
|
1953
|
-
--sdt-accent-muted: rgba(99, 102, 241, 0.1);
|
|
1954
|
-
--sdt-success: #16a34a;
|
|
1955
|
-
--sdt-success-muted: rgba(22, 163, 74, 0.1);
|
|
1956
|
-
--sdt-warning: #ca8a04;
|
|
1957
|
-
--sdt-warning-muted: rgba(202, 138, 4, 0.1);
|
|
1958
|
-
--sdt-error: #dc2626;
|
|
1959
|
-
--sdt-error-muted: rgba(220, 38, 38, 0.1);
|
|
1960
|
-
--sdt-info: #2563eb;
|
|
1961
|
-
--sdt-info-muted: rgba(37, 99, 235, 0.1);
|
|
1962
|
-
--sdt-overlay-bg: rgba(255, 255, 255, 0.92);
|
|
1963
|
-
--sdt-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.12), 0 0 0 1px rgba(0, 0, 0, 0.06);
|
|
1964
|
-
--sdt-trigger-shadow: 0 4px 12px rgba(0, 0, 0, 0.08), 0 0 0 1px rgba(0, 0, 0, 0.06);
|
|
1965
|
-
}
|
|
1966
|
-
}
|
|
1890
|
+
/* Light theme + data-stack-theme overrides come from the shared in-page-ui
|
|
1891
|
+
base styles (in-page-ui/base-styles.ts). */
|
|
1967
1892
|
|
|
1968
1893
|
/* Export dialog — positioned inside the dev tool panel */
|
|
1969
1894
|
.hexclave-devtool .sdt-share-overlay {
|
|
@@ -2701,58 +2626,4 @@ export const devToolCSS = `
|
|
|
2701
2626
|
}
|
|
2702
2627
|
}
|
|
2703
2628
|
|
|
2704
|
-
/* --- Stack theme explicit overrides (take priority over system preference) --- */
|
|
2705
|
-
html:has(head > [data-stack-theme="light"]) .hexclave-devtool {
|
|
2706
|
-
--sdt-bg: #ffffff;
|
|
2707
|
-
--sdt-bg-elevated: #f8f8fa;
|
|
2708
|
-
--sdt-bg-hover: #f0f0f3;
|
|
2709
|
-
--sdt-bg-active: #e8e8ec;
|
|
2710
|
-
--sdt-bg-subtle: #fafafa;
|
|
2711
|
-
--sdt-border: #e0e0e5;
|
|
2712
|
-
--sdt-border-subtle: #eaeaef;
|
|
2713
|
-
--sdt-text: #111113;
|
|
2714
|
-
--sdt-text-secondary: #6b6b73;
|
|
2715
|
-
--sdt-text-tertiary: #9b9ba3;
|
|
2716
|
-
--sdt-accent: #6366f1;
|
|
2717
|
-
--sdt-accent-hover: #4f46e5;
|
|
2718
|
-
--sdt-accent-muted: rgba(99, 102, 241, 0.1);
|
|
2719
|
-
--sdt-success: #16a34a;
|
|
2720
|
-
--sdt-success-muted: rgba(22, 163, 74, 0.1);
|
|
2721
|
-
--sdt-warning: #ca8a04;
|
|
2722
|
-
--sdt-warning-muted: rgba(202, 138, 4, 0.1);
|
|
2723
|
-
--sdt-error: #dc2626;
|
|
2724
|
-
--sdt-error-muted: rgba(220, 38, 38, 0.1);
|
|
2725
|
-
--sdt-info: #2563eb;
|
|
2726
|
-
--sdt-info-muted: rgba(37, 99, 235, 0.1);
|
|
2727
|
-
--sdt-overlay-bg: rgba(255, 255, 255, 0.92);
|
|
2728
|
-
--sdt-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.12), 0 0 0 1px rgba(0, 0, 0, 0.06);
|
|
2729
|
-
--sdt-trigger-shadow: 0 4px 12px rgba(0, 0, 0, 0.08), 0 0 0 1px rgba(0, 0, 0, 0.06);
|
|
2730
|
-
}
|
|
2731
|
-
|
|
2732
|
-
html:has(head > [data-stack-theme="dark"]) .hexclave-devtool {
|
|
2733
|
-
--sdt-bg: #0a0a0b;
|
|
2734
|
-
--sdt-bg-elevated: #141416;
|
|
2735
|
-
--sdt-bg-hover: #1c1c1f;
|
|
2736
|
-
--sdt-bg-active: #232326;
|
|
2737
|
-
--sdt-bg-subtle: #111113;
|
|
2738
|
-
--sdt-border: #2a2a2e;
|
|
2739
|
-
--sdt-border-subtle: #1e1e22;
|
|
2740
|
-
--sdt-text: #ececef;
|
|
2741
|
-
--sdt-text-secondary: #8b8b93;
|
|
2742
|
-
--sdt-text-tertiary: #5c5c66;
|
|
2743
|
-
--sdt-accent: #6366f1;
|
|
2744
|
-
--sdt-accent-hover: #818cf8;
|
|
2745
|
-
--sdt-accent-muted: rgba(99, 102, 241, 0.15);
|
|
2746
|
-
--sdt-success: #22c55e;
|
|
2747
|
-
--sdt-success-muted: rgba(34, 197, 94, 0.15);
|
|
2748
|
-
--sdt-warning: #eab308;
|
|
2749
|
-
--sdt-warning-muted: rgba(234, 179, 8, 0.15);
|
|
2750
|
-
--sdt-error: #ef4444;
|
|
2751
|
-
--sdt-error-muted: rgba(239, 68, 68, 0.15);
|
|
2752
|
-
--sdt-info: #3b82f6;
|
|
2753
|
-
--sdt-info-muted: rgba(59, 130, 246, 0.15);
|
|
2754
|
-
--sdt-overlay-bg: rgba(17, 17, 19, 0.92);
|
|
2755
|
-
--sdt-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.05);
|
|
2756
|
-
--sdt-trigger-shadow: 0 4px 12px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.08);
|
|
2757
|
-
}
|
|
2758
2629
|
`;
|
package/src/dev-tool/index.ts
CHANGED
|
@@ -7,25 +7,12 @@ import type { StackClientApp } from "../lib/hexclave-app";
|
|
|
7
7
|
import { captureError } from "@hexclave/shared/dist/utils/errors";
|
|
8
8
|
import { runAsynchronously } from "@hexclave/shared/dist/utils/promises";
|
|
9
9
|
import { isLocalhost } from "@hexclave/shared/dist/utils/urls";
|
|
10
|
+
import { canMountIntoDom } from "../in-page-ui/dom";
|
|
10
11
|
import type { createDevTool as CreateDevToolFn } from "./dev-tool-core";
|
|
11
12
|
|
|
12
13
|
// Hexclave rebrand: UI-only local pref — straight rename (one-time reset is harmless)
|
|
13
14
|
const OVERRIDE_KEY = '__hexclave-dev-tool-override';
|
|
14
15
|
|
|
15
|
-
function hasAppendChild(value: unknown): value is { appendChild(node: Node): void } {
|
|
16
|
-
return typeof value === 'object' && value !== null && typeof Reflect.get(value, 'appendChild') === 'function';
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function canMountIntoDom(): boolean {
|
|
20
|
-
if (typeof window === 'undefined' || typeof document === 'undefined') {
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
if (typeof document.createElement !== 'function') {
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
return hasAppendChild(Reflect.get(document, 'body'));
|
|
27
|
-
}
|
|
28
|
-
|
|
29
16
|
function getOverride(): boolean | null {
|
|
30
17
|
try {
|
|
31
18
|
const val = localStorage.getItem(OVERRIDE_KEY);
|