@webmaster-droid/web 0.1.0 → 0.2.0
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/core.css +229 -0
- package/dist/index.d.ts +18 -4
- package/dist/index.js +527 -167
- package/dist/theme.css +465 -0
- package/package.json +10 -9
- package/dist/styles.css +0 -2
package/dist/index.js
CHANGED
|
@@ -197,7 +197,7 @@ function parseSelectedEditableFromTarget(target, pagePath) {
|
|
|
197
197
|
}
|
|
198
198
|
return selected;
|
|
199
199
|
}
|
|
200
|
-
function pickStringValue(document2, path, fallback, componentName, fallbackPropName) {
|
|
200
|
+
function pickStringValue(document2, path, fallback, componentName, fallbackPropName, missingBehavior = "throw") {
|
|
201
201
|
const value = readByPath(document2, path);
|
|
202
202
|
if (typeof value === "string" && value.trim()) {
|
|
203
203
|
return value;
|
|
@@ -205,9 +205,12 @@ function pickStringValue(document2, path, fallback, componentName, fallbackPropN
|
|
|
205
205
|
if (typeof fallback === "string") {
|
|
206
206
|
return fallback;
|
|
207
207
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
208
|
+
const message = `${componentName} missing content for "${path}". Provide a CMS value or set \`${fallbackPropName}\`.`;
|
|
209
|
+
if (missingBehavior === "empty") {
|
|
210
|
+
console.error(message);
|
|
211
|
+
return "";
|
|
212
|
+
}
|
|
213
|
+
throw new Error(message);
|
|
211
214
|
}
|
|
212
215
|
function sanitizeRichTextHtml(html) {
|
|
213
216
|
return sanitizeHtml(html, {
|
|
@@ -229,7 +232,7 @@ function EditableText({
|
|
|
229
232
|
...rest
|
|
230
233
|
}) {
|
|
231
234
|
const { document: document2, enabled } = useEditableDocument();
|
|
232
|
-
const value = pickStringValue(document2, path, fallback, "EditableText", "fallback");
|
|
235
|
+
const value = pickStringValue(document2, path, fallback, "EditableText", "fallback", "empty");
|
|
233
236
|
const attrs = enabled ? editableMeta({
|
|
234
237
|
path,
|
|
235
238
|
label: label ?? path,
|
|
@@ -247,7 +250,14 @@ function EditableRichText({
|
|
|
247
250
|
...rest
|
|
248
251
|
}) {
|
|
249
252
|
const { document: document2, enabled } = useEditableDocument();
|
|
250
|
-
const value = pickStringValue(
|
|
253
|
+
const value = pickStringValue(
|
|
254
|
+
document2,
|
|
255
|
+
path,
|
|
256
|
+
fallback,
|
|
257
|
+
"EditableRichText",
|
|
258
|
+
"fallback",
|
|
259
|
+
"empty"
|
|
260
|
+
);
|
|
251
261
|
const sanitizedHtml = sanitizeRichTextHtml(value);
|
|
252
262
|
const attrs = enabled ? editableMeta({
|
|
253
263
|
path,
|
|
@@ -270,8 +280,22 @@ function EditableImage({
|
|
|
270
280
|
...rest
|
|
271
281
|
}) {
|
|
272
282
|
const { document: document2, enabled } = useEditableDocument();
|
|
273
|
-
const src = pickStringValue(
|
|
274
|
-
|
|
283
|
+
const src = pickStringValue(
|
|
284
|
+
document2,
|
|
285
|
+
path,
|
|
286
|
+
fallbackSrc,
|
|
287
|
+
"EditableImage",
|
|
288
|
+
"fallbackSrc",
|
|
289
|
+
"empty"
|
|
290
|
+
);
|
|
291
|
+
const alt = altPath ? pickStringValue(
|
|
292
|
+
document2,
|
|
293
|
+
altPath,
|
|
294
|
+
fallbackAlt,
|
|
295
|
+
"EditableImage",
|
|
296
|
+
"fallbackAlt",
|
|
297
|
+
"empty"
|
|
298
|
+
) : fallbackAlt ?? "";
|
|
275
299
|
const attrs = enabled ? editableMeta({
|
|
276
300
|
path,
|
|
277
301
|
label: label ?? path,
|
|
@@ -290,13 +314,21 @@ function EditableLink({
|
|
|
290
314
|
...rest
|
|
291
315
|
}) {
|
|
292
316
|
const { document: document2, enabled } = useEditableDocument();
|
|
293
|
-
const href = pickStringValue(
|
|
317
|
+
const href = pickStringValue(
|
|
318
|
+
document2,
|
|
319
|
+
hrefPath,
|
|
320
|
+
fallbackHref,
|
|
321
|
+
"EditableLink",
|
|
322
|
+
"fallbackHref",
|
|
323
|
+
"empty"
|
|
324
|
+
);
|
|
294
325
|
const text = pickStringValue(
|
|
295
326
|
document2,
|
|
296
327
|
labelPath,
|
|
297
328
|
fallbackLabel,
|
|
298
329
|
"EditableLink",
|
|
299
|
-
"fallbackLabel"
|
|
330
|
+
"fallbackLabel",
|
|
331
|
+
"empty"
|
|
300
332
|
);
|
|
301
333
|
const attrs = enabled ? editableMeta({
|
|
302
334
|
path: labelPath,
|
|
@@ -610,6 +642,13 @@ function getSupabaseBrowserClient(config) {
|
|
|
610
642
|
// src/context.tsx
|
|
611
643
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
612
644
|
var WebmasterDroidContext = createContext2(null);
|
|
645
|
+
var DEFAULT_MODEL_CAPABILITIES = {
|
|
646
|
+
contentEdit: true,
|
|
647
|
+
themeTokenEdit: true,
|
|
648
|
+
imageGenerate: false,
|
|
649
|
+
imageEdit: false,
|
|
650
|
+
visionAssist: false
|
|
651
|
+
};
|
|
613
652
|
function WebmasterDroidProvider(props) {
|
|
614
653
|
const resolvedConfig = useMemo(
|
|
615
654
|
() => resolveWebmasterDroidConfig(props.config),
|
|
@@ -641,6 +680,9 @@ function WebmasterDroidProvider(props) {
|
|
|
641
680
|
const [modelId, setModelId] = useState(null);
|
|
642
681
|
const [showModelPickerState, setShowModelPickerState] = useState(false);
|
|
643
682
|
const [modelOptions, setModelOptions] = useState([]);
|
|
683
|
+
const [capabilities, setCapabilities] = useState(
|
|
684
|
+
DEFAULT_MODEL_CAPABILITIES
|
|
685
|
+
);
|
|
644
686
|
const [includeThinking, setIncludeThinking] = useState(false);
|
|
645
687
|
const [refreshKey, setRefreshKey] = useState(0);
|
|
646
688
|
const [selectedElement, setSelectedElement] = useState(null);
|
|
@@ -675,6 +717,7 @@ function WebmasterDroidProvider(props) {
|
|
|
675
717
|
const preferredDefault = options.some((option) => option.id === models.defaultModelId) ? models.defaultModelId : options[0]?.id ?? models.defaultModelId;
|
|
676
718
|
setShowModelPickerState(models.showModelPicker);
|
|
677
719
|
setModelOptions(options);
|
|
720
|
+
setCapabilities(models.capabilities ?? DEFAULT_MODEL_CAPABILITIES);
|
|
678
721
|
setModelId((current) => {
|
|
679
722
|
if (current && options.some((option) => option.id === current)) {
|
|
680
723
|
return current;
|
|
@@ -685,6 +728,7 @@ function WebmasterDroidProvider(props) {
|
|
|
685
728
|
if (!ignore) {
|
|
686
729
|
setShowModelPickerState(false);
|
|
687
730
|
setModelOptions([]);
|
|
731
|
+
setCapabilities(DEFAULT_MODEL_CAPABILITIES);
|
|
688
732
|
setModelId((current) => current ?? resolvedConfig.defaultModelId);
|
|
689
733
|
}
|
|
690
734
|
});
|
|
@@ -705,6 +749,7 @@ function WebmasterDroidProvider(props) {
|
|
|
705
749
|
setModelId,
|
|
706
750
|
showModelPicker,
|
|
707
751
|
modelOptions,
|
|
752
|
+
capabilities,
|
|
708
753
|
includeThinking,
|
|
709
754
|
setIncludeThinking,
|
|
710
755
|
refreshKey,
|
|
@@ -721,6 +766,7 @@ function WebmasterDroidProvider(props) {
|
|
|
721
766
|
modelId,
|
|
722
767
|
showModelPicker,
|
|
723
768
|
modelOptions,
|
|
769
|
+
capabilities,
|
|
724
770
|
includeThinking,
|
|
725
771
|
refreshKey,
|
|
726
772
|
authConfigured,
|
|
@@ -737,6 +783,9 @@ function useWebmasterDroid() {
|
|
|
737
783
|
return context;
|
|
738
784
|
}
|
|
739
785
|
|
|
786
|
+
// src/overlay.tsx
|
|
787
|
+
import { useEffect as useEffect3 } from "react";
|
|
788
|
+
|
|
740
789
|
// src/overlay/utils.ts
|
|
741
790
|
function createMessage(role, text, status) {
|
|
742
791
|
return {
|
|
@@ -831,6 +880,84 @@ var OVERLAY_FONT_FAMILY = "var(--font-ibm-plex-mono), ui-monospace, SFMono-Regul
|
|
|
831
880
|
// src/overlay/components.tsx
|
|
832
881
|
import ReactMarkdown from "react-markdown";
|
|
833
882
|
import remarkGfm from "remark-gfm";
|
|
883
|
+
|
|
884
|
+
// src/overlay/class-names.ts
|
|
885
|
+
var OVERLAY_CLASS_NAMES = {
|
|
886
|
+
panel: "wmd-panel",
|
|
887
|
+
launcherButton: "wmd-launcher",
|
|
888
|
+
header: "wmd-header",
|
|
889
|
+
headerRow: "wmd-header-row",
|
|
890
|
+
publishState: "wmd-publish-state",
|
|
891
|
+
publishStatePublished: "wmd-publish-state--published",
|
|
892
|
+
publishStateUnpublished: "wmd-publish-state--unpublished",
|
|
893
|
+
publishButton: "wmd-publish-button",
|
|
894
|
+
tabs: "wmd-tabs",
|
|
895
|
+
tabButton: "wmd-tab-button",
|
|
896
|
+
tabButtonActive: "wmd-tab-button--active",
|
|
897
|
+
loginTitle: "wmd-login-title",
|
|
898
|
+
headerActions: "wmd-header-actions",
|
|
899
|
+
iconButton: "wmd-icon-button",
|
|
900
|
+
icon: "wmd-icon",
|
|
901
|
+
closeButton: "wmd-close-button",
|
|
902
|
+
loginSection: "wmd-login-section",
|
|
903
|
+
loginWarning: "wmd-login-warning",
|
|
904
|
+
loginCard: "wmd-login-card",
|
|
905
|
+
loginHeading: "wmd-login-heading",
|
|
906
|
+
loginFields: "wmd-login-fields",
|
|
907
|
+
fieldInput: "wmd-field-input",
|
|
908
|
+
primaryButton: "wmd-primary-button",
|
|
909
|
+
chatSection: "wmd-chat-section",
|
|
910
|
+
message: "wmd-message",
|
|
911
|
+
messageTool: "wmd-message--tool",
|
|
912
|
+
messageUser: "wmd-message--user",
|
|
913
|
+
messageThinking: "wmd-message--thinking",
|
|
914
|
+
messageAssistant: "wmd-message--assistant",
|
|
915
|
+
messageFallback: "wmd-message--fallback",
|
|
916
|
+
assistantAvatar: "wmd-assistant-avatar",
|
|
917
|
+
assistantAvatarFallback: "wmd-assistant-avatar-fallback",
|
|
918
|
+
assistantAvatarPending: "wmd-assistant-avatar--pending",
|
|
919
|
+
markdownContent: "wmd-markdown-content",
|
|
920
|
+
pendingShim: "wmd-pending-shim",
|
|
921
|
+
footer: "wmd-footer",
|
|
922
|
+
modelRow: "wmd-model-row",
|
|
923
|
+
modelLabel: "wmd-model-label",
|
|
924
|
+
modelSelect: "wmd-model-select",
|
|
925
|
+
selectedElement: "wmd-selected-element",
|
|
926
|
+
selectedKind: "wmd-selected-kind",
|
|
927
|
+
selectedText: "wmd-selected-text",
|
|
928
|
+
selectedLabel: "wmd-selected-label",
|
|
929
|
+
selectedClearButton: "wmd-selected-clear",
|
|
930
|
+
selectedClearIcon: "wmd-selected-clear-icon",
|
|
931
|
+
composerRow: "wmd-composer-row",
|
|
932
|
+
composerInput: "wmd-composer-input",
|
|
933
|
+
sendButton: "wmd-send-button",
|
|
934
|
+
historySection: "wmd-history-section",
|
|
935
|
+
historyColumns: "wmd-history-columns",
|
|
936
|
+
historyCard: "wmd-history-card",
|
|
937
|
+
historyCardTitle: "wmd-history-card-title",
|
|
938
|
+
historyList: "wmd-history-list",
|
|
939
|
+
historyStack: "wmd-history-stack",
|
|
940
|
+
historyItem: "wmd-history-item",
|
|
941
|
+
historyItemCheckpoint: "wmd-history-item--checkpoint",
|
|
942
|
+
historyTextBlock: "wmd-history-text",
|
|
943
|
+
historyTimestamp: "wmd-history-timestamp",
|
|
944
|
+
historyReason: "wmd-history-reason",
|
|
945
|
+
historyActions: "wmd-history-actions",
|
|
946
|
+
historyAction: "wmd-history-action",
|
|
947
|
+
historyDelete: "wmd-history-delete",
|
|
948
|
+
emptyText: "wmd-empty-text"
|
|
949
|
+
};
|
|
950
|
+
function overlayClass(slot, className) {
|
|
951
|
+
if (!className) {
|
|
952
|
+
return OVERLAY_CLASS_NAMES[slot];
|
|
953
|
+
}
|
|
954
|
+
return `${OVERLAY_CLASS_NAMES[slot]} ${className}`;
|
|
955
|
+
}
|
|
956
|
+
function joinClassNames(...parts) {
|
|
957
|
+
return parts.filter(Boolean).join(" ");
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
// src/overlay/components.tsx
|
|
834
961
|
import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
835
962
|
function OverlayHeader({
|
|
836
963
|
isAuthenticated,
|
|
@@ -843,12 +970,15 @@ function OverlayHeader({
|
|
|
843
970
|
onClearChat,
|
|
844
971
|
onClose
|
|
845
972
|
}) {
|
|
846
|
-
return /* @__PURE__ */ jsx3("header", { className: "border-b border-stone-300 bg-[#f3eee5] p-2", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
973
|
+
return /* @__PURE__ */ jsx3("header", { className: overlayClass("header", "border-b border-stone-300 bg-[#f3eee5] p-2"), children: /* @__PURE__ */ jsxs("div", { className: overlayClass("headerRow", "flex items-center gap-2"), children: [
|
|
847
974
|
isAuthenticated ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
848
975
|
/* @__PURE__ */ jsx3(
|
|
849
976
|
"span",
|
|
850
977
|
{
|
|
851
|
-
className:
|
|
978
|
+
className: joinClassNames(
|
|
979
|
+
overlayClass("publishState", "rounded border px-1.5 py-0.5 text-[10px] font-medium leading-4"),
|
|
980
|
+
publishState === "Published" ? overlayClass("publishStatePublished", "border-stone-300 bg-[#ece5d9] text-stone-600") : overlayClass("publishStateUnpublished", "border-stone-500 bg-[#ded4c3] text-stone-800")
|
|
981
|
+
),
|
|
852
982
|
children: publishState
|
|
853
983
|
}
|
|
854
984
|
),
|
|
@@ -856,18 +986,24 @@ function OverlayHeader({
|
|
|
856
986
|
"button",
|
|
857
987
|
{
|
|
858
988
|
type: "button",
|
|
859
|
-
className:
|
|
989
|
+
className: overlayClass(
|
|
990
|
+
"publishButton",
|
|
991
|
+
"rounded border border-stone-700 bg-stone-800 px-2 py-1 text-[11px] font-semibold leading-4 text-stone-100 hover:bg-stone-700 disabled:cursor-not-allowed disabled:opacity-50"
|
|
992
|
+
),
|
|
860
993
|
onClick: onPublish,
|
|
861
994
|
disabled: !isAuthenticated,
|
|
862
995
|
children: "Publish"
|
|
863
996
|
}
|
|
864
997
|
),
|
|
865
|
-
/* @__PURE__ */ jsxs("div", { className: "inline-flex rounded-md border border-stone-300 bg-[#e8dfd1] p-0.5", children: [
|
|
998
|
+
/* @__PURE__ */ jsxs("div", { className: overlayClass("tabs", "inline-flex rounded-md border border-stone-300 bg-[#e8dfd1] p-0.5"), children: [
|
|
866
999
|
/* @__PURE__ */ jsx3(
|
|
867
1000
|
"button",
|
|
868
1001
|
{
|
|
869
1002
|
type: "button",
|
|
870
|
-
className:
|
|
1003
|
+
className: joinClassNames(
|
|
1004
|
+
overlayClass("tabButton", "rounded px-2 py-1 text-[11px] font-medium leading-4"),
|
|
1005
|
+
activeTab === "chat" ? overlayClass("tabButtonActive", "bg-[#f7f2e8] text-stone-900 shadow-sm") : "text-stone-600 hover:text-stone-900"
|
|
1006
|
+
),
|
|
871
1007
|
onClick: () => onTabChange("chat"),
|
|
872
1008
|
children: "Chat"
|
|
873
1009
|
}
|
|
@@ -876,7 +1012,10 @@ function OverlayHeader({
|
|
|
876
1012
|
"button",
|
|
877
1013
|
{
|
|
878
1014
|
type: "button",
|
|
879
|
-
className:
|
|
1015
|
+
className: joinClassNames(
|
|
1016
|
+
overlayClass("tabButton", "rounded px-2 py-1 text-[11px] font-medium leading-4"),
|
|
1017
|
+
activeTab === "history" ? overlayClass("tabButtonActive", "bg-[#f7f2e8] text-stone-900 shadow-sm") : "text-stone-600 hover:text-stone-900"
|
|
1018
|
+
),
|
|
880
1019
|
onClick: () => onTabChange("history"),
|
|
881
1020
|
children: [
|
|
882
1021
|
"History (",
|
|
@@ -886,8 +1025,8 @@ function OverlayHeader({
|
|
|
886
1025
|
}
|
|
887
1026
|
)
|
|
888
1027
|
] })
|
|
889
|
-
] }) : /* @__PURE__ */ jsx3("h2", { className: "text-[12px] font-semibold text-stone-700", children: "Login" }),
|
|
890
|
-
/* @__PURE__ */ jsxs("div", { className: "ml-auto flex items-center gap-1", children: [
|
|
1028
|
+
] }) : /* @__PURE__ */ jsx3("h2", { className: overlayClass("loginTitle", "text-[12px] font-semibold text-stone-700"), children: "Login" }),
|
|
1029
|
+
/* @__PURE__ */ jsxs("div", { className: overlayClass("headerActions", "ml-auto flex items-center gap-1"), children: [
|
|
891
1030
|
isAuthenticated ? /* @__PURE__ */ jsx3(
|
|
892
1031
|
"button",
|
|
893
1032
|
{
|
|
@@ -895,25 +1034,40 @@ function OverlayHeader({
|
|
|
895
1034
|
"aria-label": "Clear chat",
|
|
896
1035
|
title: "Clear chat",
|
|
897
1036
|
disabled: clearChatDisabled,
|
|
898
|
-
className:
|
|
1037
|
+
className: overlayClass(
|
|
1038
|
+
"iconButton",
|
|
1039
|
+
"inline-flex h-6 w-6 items-center justify-center rounded border border-stone-300 text-stone-600 hover:bg-[#efe8dc] hover:text-stone-800 disabled:cursor-not-allowed disabled:opacity-50"
|
|
1040
|
+
),
|
|
899
1041
|
onClick: onClearChat,
|
|
900
|
-
children: /* @__PURE__ */ jsx3(
|
|
901
|
-
"
|
|
1042
|
+
children: /* @__PURE__ */ jsx3(
|
|
1043
|
+
"svg",
|
|
902
1044
|
{
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
1045
|
+
viewBox: "0 0 20 20",
|
|
1046
|
+
fill: "none",
|
|
1047
|
+
className: overlayClass("icon", "h-3.5 w-3.5"),
|
|
1048
|
+
"aria-hidden": "true",
|
|
1049
|
+
children: /* @__PURE__ */ jsx3(
|
|
1050
|
+
"path",
|
|
1051
|
+
{
|
|
1052
|
+
d: "M4.5 5.5H15.5M8 3.75H12M7 7.5V13.5M10 7.5V13.5M13 7.5V13.5M6.5 5.5L7 15C7.03 15.6 7.53 16.08 8.13 16.08H11.87C12.47 16.08 12.97 15.6 13 15L13.5 5.5",
|
|
1053
|
+
stroke: "currentColor",
|
|
1054
|
+
strokeWidth: "1.4",
|
|
1055
|
+
strokeLinecap: "round",
|
|
1056
|
+
strokeLinejoin: "round"
|
|
1057
|
+
}
|
|
1058
|
+
)
|
|
908
1059
|
}
|
|
909
|
-
)
|
|
1060
|
+
)
|
|
910
1061
|
}
|
|
911
1062
|
) : null,
|
|
912
1063
|
/* @__PURE__ */ jsx3(
|
|
913
1064
|
"button",
|
|
914
1065
|
{
|
|
915
1066
|
type: "button",
|
|
916
|
-
className:
|
|
1067
|
+
className: overlayClass(
|
|
1068
|
+
"closeButton",
|
|
1069
|
+
"rounded border border-stone-300 px-2 py-1 text-[11px] leading-4 text-stone-700 hover:bg-[#efe8dc]"
|
|
1070
|
+
),
|
|
917
1071
|
onClick: onClose,
|
|
918
1072
|
children: "Close"
|
|
919
1073
|
}
|
|
@@ -930,41 +1084,68 @@ function OverlayLoginPanel({
|
|
|
930
1084
|
onPasswordChange,
|
|
931
1085
|
onSignIn
|
|
932
1086
|
}) {
|
|
933
|
-
return /* @__PURE__ */ jsx3(
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
"
|
|
938
|
-
|
|
939
|
-
type: "text",
|
|
940
|
-
value: email,
|
|
941
|
-
onChange: (event) => onEmailChange(event.target.value),
|
|
942
|
-
placeholder: "login",
|
|
943
|
-
className: "w-full rounded border border-stone-300 bg-[#f4efe6] px-2 py-1.5 text-[12px] text-stone-900 outline-none focus:border-stone-500"
|
|
944
|
-
}
|
|
945
|
-
),
|
|
946
|
-
/* @__PURE__ */ jsx3(
|
|
947
|
-
"input",
|
|
948
|
-
{
|
|
949
|
-
type: "password",
|
|
950
|
-
value: password,
|
|
951
|
-
onChange: (event) => onPasswordChange(event.target.value),
|
|
952
|
-
placeholder: "Password",
|
|
953
|
-
className: "w-full rounded border border-stone-300 bg-[#f4efe6] px-2 py-1.5 text-[12px] text-stone-900 outline-none focus:border-stone-500"
|
|
954
|
-
}
|
|
1087
|
+
return /* @__PURE__ */ jsx3(
|
|
1088
|
+
"section",
|
|
1089
|
+
{
|
|
1090
|
+
className: overlayClass(
|
|
1091
|
+
"loginSection",
|
|
1092
|
+
"flex min-h-0 flex-1 items-center justify-center bg-[#ece7dd] p-3"
|
|
955
1093
|
),
|
|
956
|
-
/* @__PURE__ */ jsx3(
|
|
957
|
-
"
|
|
1094
|
+
children: !authConfigured ? /* @__PURE__ */ jsx3(
|
|
1095
|
+
"div",
|
|
958
1096
|
{
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
children:
|
|
1097
|
+
className: overlayClass(
|
|
1098
|
+
"loginWarning",
|
|
1099
|
+
"w-full max-w-sm rounded border border-red-300 bg-[#f8f3e9] p-3 text-[11px] leading-4 text-red-700"
|
|
1100
|
+
),
|
|
1101
|
+
children: "Missing Supabase config (`supabaseUrl` / `supabaseAnonKey`)."
|
|
964
1102
|
}
|
|
965
|
-
)
|
|
966
|
-
|
|
967
|
-
|
|
1103
|
+
) : /* @__PURE__ */ jsxs("div", { className: overlayClass("loginCard", "w-full max-w-sm rounded border border-stone-300 bg-[#f8f3e9] p-3"), children: [
|
|
1104
|
+
/* @__PURE__ */ jsx3("h3", { className: overlayClass("loginHeading", "mb-2 text-[12px] font-semibold text-stone-700"), children: "Sign in" }),
|
|
1105
|
+
/* @__PURE__ */ jsxs("div", { className: overlayClass("loginFields", "space-y-2"), children: [
|
|
1106
|
+
/* @__PURE__ */ jsx3(
|
|
1107
|
+
"input",
|
|
1108
|
+
{
|
|
1109
|
+
type: "text",
|
|
1110
|
+
value: email,
|
|
1111
|
+
onChange: (event) => onEmailChange(event.target.value),
|
|
1112
|
+
placeholder: "login",
|
|
1113
|
+
className: overlayClass(
|
|
1114
|
+
"fieldInput",
|
|
1115
|
+
"w-full rounded border border-stone-300 bg-[#f4efe6] px-2 py-1.5 text-[12px] text-stone-900 outline-none focus:border-stone-500"
|
|
1116
|
+
)
|
|
1117
|
+
}
|
|
1118
|
+
),
|
|
1119
|
+
/* @__PURE__ */ jsx3(
|
|
1120
|
+
"input",
|
|
1121
|
+
{
|
|
1122
|
+
type: "password",
|
|
1123
|
+
value: password,
|
|
1124
|
+
onChange: (event) => onPasswordChange(event.target.value),
|
|
1125
|
+
placeholder: "Password",
|
|
1126
|
+
className: overlayClass(
|
|
1127
|
+
"fieldInput",
|
|
1128
|
+
"w-full rounded border border-stone-300 bg-[#f4efe6] px-2 py-1.5 text-[12px] text-stone-900 outline-none focus:border-stone-500"
|
|
1129
|
+
)
|
|
1130
|
+
}
|
|
1131
|
+
),
|
|
1132
|
+
/* @__PURE__ */ jsx3(
|
|
1133
|
+
"button",
|
|
1134
|
+
{
|
|
1135
|
+
type: "button",
|
|
1136
|
+
onClick: onSignIn,
|
|
1137
|
+
disabled: signingIn || !email.trim() || !password,
|
|
1138
|
+
className: overlayClass(
|
|
1139
|
+
"primaryButton",
|
|
1140
|
+
"w-full rounded border border-stone-700 bg-stone-800 px-2 py-1.5 text-[12px] font-medium text-stone-100 hover:bg-stone-700 disabled:cursor-not-allowed disabled:opacity-50"
|
|
1141
|
+
),
|
|
1142
|
+
children: signingIn ? "Signing in" : "Sign in"
|
|
1143
|
+
}
|
|
1144
|
+
)
|
|
1145
|
+
] })
|
|
1146
|
+
] })
|
|
1147
|
+
}
|
|
1148
|
+
);
|
|
968
1149
|
}
|
|
969
1150
|
function OverlayChatPanel({
|
|
970
1151
|
messages,
|
|
@@ -987,14 +1168,29 @@ function OverlayChatPanel({
|
|
|
987
1168
|
isAuthenticated
|
|
988
1169
|
}) {
|
|
989
1170
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
990
|
-
/* @__PURE__ */ jsxs("section", { className: "flex-1 space-y-1 overflow-auto bg-[#ece7dd] p-2", children: [
|
|
1171
|
+
/* @__PURE__ */ jsxs("section", { className: overlayClass("chatSection", "flex-1 space-y-1 overflow-auto bg-[#ece7dd] p-2"), children: [
|
|
991
1172
|
messages.map((entry) => {
|
|
992
1173
|
const isAssistant = entry.role === "assistant";
|
|
993
1174
|
const isPendingAssistant = isAssistant && entry.status === "pending";
|
|
994
1175
|
return /* @__PURE__ */ jsx3(
|
|
995
1176
|
"div",
|
|
996
1177
|
{
|
|
997
|
-
className:
|
|
1178
|
+
className: joinClassNames(
|
|
1179
|
+
overlayClass("message"),
|
|
1180
|
+
entry.role === "tool" ? overlayClass("messageTool", "max-w-[96%] px-0.5 py-0 text-[10px] leading-tight text-stone-500") : entry.role === "user" ? overlayClass(
|
|
1181
|
+
"messageUser",
|
|
1182
|
+
"ml-auto max-w-[92%] rounded-md bg-[#2e2b27] px-2 py-1.5 text-[12px] leading-4 text-stone-50"
|
|
1183
|
+
) : entry.role === "thinking" ? overlayClass(
|
|
1184
|
+
"messageThinking",
|
|
1185
|
+
"max-w-[92%] rounded-md bg-[#e3dbce] px-2 py-1.5 text-[12px] leading-4 text-stone-700"
|
|
1186
|
+
) : isAssistant ? overlayClass(
|
|
1187
|
+
"messageAssistant",
|
|
1188
|
+
"relative max-w-[92%] rounded-md border border-[#d6ccbb] bg-[#f8f3e9] pl-8 pr-2 py-1.5 text-[12px] leading-4 text-stone-800"
|
|
1189
|
+
) : overlayClass(
|
|
1190
|
+
"messageFallback",
|
|
1191
|
+
"max-w-[92%] rounded-md bg-[#ddd2bf] px-2 py-1.5 text-[12px] leading-4 text-stone-800"
|
|
1192
|
+
)
|
|
1193
|
+
),
|
|
998
1194
|
children: entry.role === "tool" ? /* @__PURE__ */ jsx3("span", { children: entry.text }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
999
1195
|
isAssistant ? showAssistantAvatarImage ? /* @__PURE__ */ jsx3(
|
|
1000
1196
|
"img",
|
|
@@ -1002,18 +1198,39 @@ function OverlayChatPanel({
|
|
|
1002
1198
|
src: assistantAvatarUrl,
|
|
1003
1199
|
alt: "",
|
|
1004
1200
|
"aria-hidden": "true",
|
|
1005
|
-
className:
|
|
1201
|
+
className: joinClassNames(
|
|
1202
|
+
overlayClass(
|
|
1203
|
+
"assistantAvatar",
|
|
1204
|
+
"pointer-events-none absolute left-2 top-1.5 h-[18px] w-[18px] select-none rounded-full border border-[#d6ccbb] bg-[#efe8dc] object-cover"
|
|
1205
|
+
),
|
|
1206
|
+
isPendingAssistant ? overlayClass("assistantAvatarPending", "animate-pulse") : null
|
|
1207
|
+
),
|
|
1006
1208
|
onError: onAssistantAvatarError
|
|
1007
1209
|
}
|
|
1008
1210
|
) : /* @__PURE__ */ jsx3(
|
|
1009
1211
|
"span",
|
|
1010
1212
|
{
|
|
1011
1213
|
"aria-hidden": "true",
|
|
1012
|
-
className:
|
|
1214
|
+
className: joinClassNames(
|
|
1215
|
+
overlayClass(
|
|
1216
|
+
"assistantAvatarFallback",
|
|
1217
|
+
"pointer-events-none absolute left-2 top-1.5 inline-flex h-[18px] w-[18px] select-none items-center justify-center rounded-full border border-[#d6ccbb] bg-[#efe8dc] text-[9px] font-semibold text-stone-700"
|
|
1218
|
+
),
|
|
1219
|
+
isPendingAssistant ? overlayClass("assistantAvatarPending", "animate-pulse") : null
|
|
1220
|
+
),
|
|
1013
1221
|
children: assistantAvatarFallbackLabel
|
|
1014
1222
|
}
|
|
1015
1223
|
) : null,
|
|
1016
|
-
/* @__PURE__ */ jsx3(
|
|
1224
|
+
/* @__PURE__ */ jsx3(
|
|
1225
|
+
"div",
|
|
1226
|
+
{
|
|
1227
|
+
className: overlayClass(
|
|
1228
|
+
"markdownContent",
|
|
1229
|
+
"max-w-none text-inherit [&_code]:rounded [&_code]:bg-stone-900/10 [&_code]:px-1 [&_ol]:list-decimal [&_ol]:pl-4 [&_p]:mb-1 [&_p:last-child]:mb-0 [&_ul]:list-disc [&_ul]:pl-4"
|
|
1230
|
+
),
|
|
1231
|
+
children: isPendingAssistant && !entry.text.trim() ? /* @__PURE__ */ jsx3("span", { className: overlayClass("pendingShim", "block h-4"), "aria-hidden": "true" }) : /* @__PURE__ */ jsx3(ReactMarkdown, { remarkPlugins: [remarkGfm], children: entry.text })
|
|
1232
|
+
}
|
|
1233
|
+
)
|
|
1017
1234
|
] })
|
|
1018
1235
|
},
|
|
1019
1236
|
entry.id
|
|
@@ -1021,13 +1238,13 @@ function OverlayChatPanel({
|
|
|
1021
1238
|
}),
|
|
1022
1239
|
/* @__PURE__ */ jsx3("div", { ref: chatEndRef })
|
|
1023
1240
|
] }),
|
|
1024
|
-
/* @__PURE__ */ jsxs("footer", { className: "border-t border-stone-300 bg-[#f3eee5] p-2", children: [
|
|
1025
|
-
showModelPicker && selectableModels.length > 1 ? /* @__PURE__ */ jsxs("div", { className: "mb-1 flex items-center gap-1.5", children: [
|
|
1241
|
+
/* @__PURE__ */ jsxs("footer", { className: overlayClass("footer", "border-t border-stone-300 bg-[#f3eee5] p-2"), children: [
|
|
1242
|
+
showModelPicker && selectableModels.length > 1 ? /* @__PURE__ */ jsxs("div", { className: overlayClass("modelRow", "mb-1 flex items-center gap-1.5"), children: [
|
|
1026
1243
|
/* @__PURE__ */ jsx3(
|
|
1027
1244
|
"label",
|
|
1028
1245
|
{
|
|
1029
1246
|
htmlFor: "admin-model-picker",
|
|
1030
|
-
className: "text-[10px] font-semibold uppercase tracking-wide text-stone-600",
|
|
1247
|
+
className: overlayClass("modelLabel", "text-[10px] font-semibold uppercase tracking-wide text-stone-600"),
|
|
1031
1248
|
children: "Model"
|
|
1032
1249
|
}
|
|
1033
1250
|
),
|
|
@@ -1038,45 +1255,78 @@ function OverlayChatPanel({
|
|
|
1038
1255
|
value: modelId ?? selectableModels[0]?.id,
|
|
1039
1256
|
onChange: (event) => onModelChange(event.target.value),
|
|
1040
1257
|
disabled: sending,
|
|
1041
|
-
className:
|
|
1258
|
+
className: overlayClass(
|
|
1259
|
+
"modelSelect",
|
|
1260
|
+
"h-7 min-w-0 flex-1 rounded border border-stone-300 bg-[#f7f2e8] px-2 text-[11px] text-stone-800 outline-none focus:border-stone-500 disabled:cursor-not-allowed disabled:opacity-60"
|
|
1261
|
+
),
|
|
1042
1262
|
children: selectableModels.map((option) => /* @__PURE__ */ jsx3("option", { value: option.id, children: option.label }, option.id))
|
|
1043
1263
|
}
|
|
1044
1264
|
)
|
|
1045
1265
|
] }) : null,
|
|
1046
|
-
selectedElement ? /* @__PURE__ */ jsxs(
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
"
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
selectedElement.preview
|
|
1057
|
-
] }) : null
|
|
1058
|
-
] }),
|
|
1059
|
-
/* @__PURE__ */ jsx3(
|
|
1060
|
-
"button",
|
|
1061
|
-
{
|
|
1062
|
-
type: "button",
|
|
1063
|
-
"aria-label": "Clear selected element",
|
|
1064
|
-
title: "Clear selected element",
|
|
1065
|
-
className: "inline-flex h-5 w-5 shrink-0 items-center justify-center rounded border border-stone-300 bg-[#f7f2e8] text-stone-700 hover:bg-[#efe8dc]",
|
|
1066
|
-
onClick: onClearSelectedElement,
|
|
1067
|
-
children: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 20 20", fill: "none", className: "h-3 w-3", "aria-hidden": "true", children: /* @__PURE__ */ jsx3(
|
|
1068
|
-
"path",
|
|
1266
|
+
selectedElement ? /* @__PURE__ */ jsxs(
|
|
1267
|
+
"div",
|
|
1268
|
+
{
|
|
1269
|
+
className: overlayClass(
|
|
1270
|
+
"selectedElement",
|
|
1271
|
+
"mb-1 flex items-center gap-1 rounded border border-stone-300 bg-[#e8dfd1] px-1.5 py-1"
|
|
1272
|
+
),
|
|
1273
|
+
children: [
|
|
1274
|
+
/* @__PURE__ */ jsx3(
|
|
1275
|
+
"span",
|
|
1069
1276
|
{
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1277
|
+
className: overlayClass(
|
|
1278
|
+
"selectedKind",
|
|
1279
|
+
"inline-flex shrink-0 items-center justify-center rounded border border-stone-300 bg-[#f7f2e8] px-1 py-0.5 text-[9px] font-semibold text-stone-700"
|
|
1280
|
+
),
|
|
1281
|
+
children: kindIcon(selectedElement.kind)
|
|
1074
1282
|
}
|
|
1075
|
-
)
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1283
|
+
),
|
|
1284
|
+
/* @__PURE__ */ jsxs("p", { className: overlayClass("selectedText", "min-w-0 flex-1 truncate text-[10px] leading-3.5 text-stone-600"), children: [
|
|
1285
|
+
/* @__PURE__ */ jsx3("span", { className: overlayClass("selectedLabel", "font-semibold text-stone-800"), children: selectedElement.label }),
|
|
1286
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
1287
|
+
" \xB7 ",
|
|
1288
|
+
selectedElement.path
|
|
1289
|
+
] }),
|
|
1290
|
+
selectedElement.preview ? /* @__PURE__ */ jsxs("span", { children: [
|
|
1291
|
+
" \xB7 ",
|
|
1292
|
+
selectedElement.preview
|
|
1293
|
+
] }) : null
|
|
1294
|
+
] }),
|
|
1295
|
+
/* @__PURE__ */ jsx3(
|
|
1296
|
+
"button",
|
|
1297
|
+
{
|
|
1298
|
+
type: "button",
|
|
1299
|
+
"aria-label": "Clear selected element",
|
|
1300
|
+
title: "Clear selected element",
|
|
1301
|
+
className: overlayClass(
|
|
1302
|
+
"selectedClearButton",
|
|
1303
|
+
"inline-flex h-5 w-5 shrink-0 items-center justify-center rounded border border-stone-300 bg-[#f7f2e8] text-stone-700 hover:bg-[#efe8dc]"
|
|
1304
|
+
),
|
|
1305
|
+
onClick: onClearSelectedElement,
|
|
1306
|
+
children: /* @__PURE__ */ jsx3(
|
|
1307
|
+
"svg",
|
|
1308
|
+
{
|
|
1309
|
+
viewBox: "0 0 20 20",
|
|
1310
|
+
fill: "none",
|
|
1311
|
+
className: overlayClass("selectedClearIcon", "h-3 w-3"),
|
|
1312
|
+
"aria-hidden": "true",
|
|
1313
|
+
children: /* @__PURE__ */ jsx3(
|
|
1314
|
+
"path",
|
|
1315
|
+
{
|
|
1316
|
+
d: "M5 5L15 15M15 5L5 15",
|
|
1317
|
+
stroke: "currentColor",
|
|
1318
|
+
strokeWidth: "1.5",
|
|
1319
|
+
strokeLinecap: "round"
|
|
1320
|
+
}
|
|
1321
|
+
)
|
|
1322
|
+
}
|
|
1323
|
+
)
|
|
1324
|
+
}
|
|
1325
|
+
)
|
|
1326
|
+
]
|
|
1327
|
+
}
|
|
1328
|
+
) : null,
|
|
1329
|
+
/* @__PURE__ */ jsxs("div", { className: overlayClass("composerRow", "flex gap-1.5"), children: [
|
|
1080
1330
|
/* @__PURE__ */ jsx3(
|
|
1081
1331
|
"textarea",
|
|
1082
1332
|
{
|
|
@@ -1085,7 +1335,10 @@ function OverlayChatPanel({
|
|
|
1085
1335
|
onKeyDown: onMessageKeyDown,
|
|
1086
1336
|
rows: 2,
|
|
1087
1337
|
placeholder: "Ask the agent to edit text, image URLs, or theme tokens",
|
|
1088
|
-
className:
|
|
1338
|
+
className: overlayClass(
|
|
1339
|
+
"composerInput",
|
|
1340
|
+
"flex-1 resize-none rounded border border-stone-300 bg-[#f4efe6] px-2 py-1.5 text-[12px] leading-4 text-stone-900 outline-none placeholder:text-stone-500 focus:border-stone-500"
|
|
1341
|
+
)
|
|
1089
1342
|
}
|
|
1090
1343
|
),
|
|
1091
1344
|
/* @__PURE__ */ jsx3(
|
|
@@ -1094,7 +1347,10 @@ function OverlayChatPanel({
|
|
|
1094
1347
|
type: "button",
|
|
1095
1348
|
onClick: onSend,
|
|
1096
1349
|
disabled: !isAuthenticated || sending || !message.trim(),
|
|
1097
|
-
className:
|
|
1350
|
+
className: overlayClass(
|
|
1351
|
+
"sendButton",
|
|
1352
|
+
"rounded border border-stone-500 bg-stone-600 px-3 py-1.5 text-[12px] font-semibold text-stone-100 hover:bg-stone-700 disabled:cursor-not-allowed disabled:opacity-50"
|
|
1353
|
+
),
|
|
1098
1354
|
children: sending ? "Sending" : "Send"
|
|
1099
1355
|
}
|
|
1100
1356
|
)
|
|
@@ -1109,24 +1365,30 @@ function OverlayHistoryPanel({
|
|
|
1109
1365
|
onRestoreCheckpoint,
|
|
1110
1366
|
onDeleteCheckpoint
|
|
1111
1367
|
}) {
|
|
1112
|
-
return /* @__PURE__ */ jsx3("section", { className: "flex min-h-0 flex-1 flex-col p-2 text-[11px] leading-4", children: /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1 flex-col gap-2 overflow-hidden", children: [
|
|
1113
|
-
/* @__PURE__ */ jsxs("div", { className: "rounded border border-stone-300 bg-[#f8f3e9]", children: [
|
|
1114
|
-
/* @__PURE__ */ jsxs("div", { className: "border-b border-stone-200 px-2 py-1 font-semibold text-stone-700", children: [
|
|
1368
|
+
return /* @__PURE__ */ jsx3("section", { className: overlayClass("historySection", "flex min-h-0 flex-1 flex-col p-2 text-[11px] leading-4"), children: /* @__PURE__ */ jsxs("div", { className: overlayClass("historyColumns", "flex min-h-0 flex-1 flex-col gap-2 overflow-hidden"), children: [
|
|
1369
|
+
/* @__PURE__ */ jsxs("div", { className: overlayClass("historyCard", "rounded border border-stone-300 bg-[#f8f3e9]"), children: [
|
|
1370
|
+
/* @__PURE__ */ jsxs("div", { className: overlayClass("historyCardTitle", "border-b border-stone-200 px-2 py-1 font-semibold text-stone-700"), children: [
|
|
1115
1371
|
"Published (",
|
|
1116
1372
|
history.published.length,
|
|
1117
1373
|
")"
|
|
1118
1374
|
] }),
|
|
1119
|
-
/* @__PURE__ */ jsx3("div", { className: "max-h-40 overflow-auto px-2 py-1.5", children: history.published.length > 0 ? /* @__PURE__ */ jsx3("div", { className: "space-y-1", children: history.published.map((item) => /* @__PURE__ */ jsxs(
|
|
1375
|
+
/* @__PURE__ */ jsx3("div", { className: overlayClass("historyList", "max-h-40 overflow-auto px-2 py-1.5"), children: history.published.length > 0 ? /* @__PURE__ */ jsx3("div", { className: overlayClass("historyStack", "space-y-1"), children: history.published.map((item) => /* @__PURE__ */ jsxs(
|
|
1120
1376
|
"div",
|
|
1121
1377
|
{
|
|
1122
|
-
className:
|
|
1378
|
+
className: overlayClass(
|
|
1379
|
+
"historyItem",
|
|
1380
|
+
"flex items-center justify-between gap-2 rounded border border-stone-200 bg-[#f2ecdf] px-2 py-1"
|
|
1381
|
+
),
|
|
1123
1382
|
children: [
|
|
1124
|
-
/* @__PURE__ */ jsx3("span", { className: "truncate text-[10px] text-stone-700", children: formatHistoryTime(item.createdAt) }),
|
|
1383
|
+
/* @__PURE__ */ jsx3("span", { className: overlayClass("historyTimestamp", "truncate text-[10px] text-stone-700"), children: formatHistoryTime(item.createdAt) }),
|
|
1125
1384
|
/* @__PURE__ */ jsx3(
|
|
1126
1385
|
"button",
|
|
1127
1386
|
{
|
|
1128
1387
|
type: "button",
|
|
1129
|
-
className:
|
|
1388
|
+
className: overlayClass(
|
|
1389
|
+
"historyAction",
|
|
1390
|
+
"rounded border border-stone-300 bg-[#f7f2e8] px-1.5 py-0.5 text-[10px] text-stone-700 hover:bg-[#efe8dc]"
|
|
1391
|
+
),
|
|
1130
1392
|
onClick: () => onRestorePublished(item),
|
|
1131
1393
|
children: "Restore"
|
|
1132
1394
|
}
|
|
@@ -1134,61 +1396,88 @@ function OverlayHistoryPanel({
|
|
|
1134
1396
|
]
|
|
1135
1397
|
},
|
|
1136
1398
|
`pub-${item.id}`
|
|
1137
|
-
)) }) : /* @__PURE__ */ jsx3("p", { className: "text-[10px] text-stone-500", children: "No published snapshots." }) })
|
|
1399
|
+
)) }) : /* @__PURE__ */ jsx3("p", { className: overlayClass("emptyText", "text-[10px] text-stone-500"), children: "No published snapshots." }) })
|
|
1138
1400
|
] }),
|
|
1139
|
-
/* @__PURE__ */ jsxs(
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
"
|
|
1157
|
-
|
|
1158
|
-
type: "button",
|
|
1159
|
-
disabled: deletingCheckpointId === item.id,
|
|
1160
|
-
className: "rounded border border-stone-300 bg-[#f7f2e8] px-1.5 py-0.5 text-[10px] text-stone-700 hover:bg-[#efe8dc] disabled:cursor-not-allowed disabled:opacity-50",
|
|
1161
|
-
onClick: () => onRestoreCheckpoint(item),
|
|
1162
|
-
children: "Restore"
|
|
1163
|
-
}
|
|
1401
|
+
/* @__PURE__ */ jsxs(
|
|
1402
|
+
"div",
|
|
1403
|
+
{
|
|
1404
|
+
className: overlayClass(
|
|
1405
|
+
"historyCard",
|
|
1406
|
+
"flex min-h-0 flex-1 flex-col rounded border border-stone-300 bg-[#f8f3e9]"
|
|
1407
|
+
),
|
|
1408
|
+
children: [
|
|
1409
|
+
/* @__PURE__ */ jsxs("div", { className: overlayClass("historyCardTitle", "border-b border-stone-200 px-2 py-1 font-semibold text-stone-700"), children: [
|
|
1410
|
+
"Checkpoints (",
|
|
1411
|
+
history.checkpoints.length,
|
|
1412
|
+
")"
|
|
1413
|
+
] }),
|
|
1414
|
+
/* @__PURE__ */ jsx3("div", { className: overlayClass("historyList", "min-h-0 flex-1 overflow-auto px-2 py-1.5"), children: history.checkpoints.length > 0 ? /* @__PURE__ */ jsx3("div", { className: overlayClass("historyStack", "space-y-1"), children: history.checkpoints.map((item) => /* @__PURE__ */ jsxs(
|
|
1415
|
+
"div",
|
|
1416
|
+
{
|
|
1417
|
+
className: overlayClass(
|
|
1418
|
+
"historyItemCheckpoint",
|
|
1419
|
+
"flex items-start justify-between gap-2 rounded border border-stone-200 bg-[#f2ecdf] px-2 py-1"
|
|
1164
1420
|
),
|
|
1165
|
-
|
|
1166
|
-
"
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
onClick: () => onDeleteCheckpoint(item),
|
|
1174
|
-
children: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 20 20", fill: "none", className: "h-3.5 w-3.5", "aria-hidden": "true", children: /* @__PURE__ */ jsx3(
|
|
1175
|
-
"path",
|
|
1421
|
+
children: [
|
|
1422
|
+
/* @__PURE__ */ jsxs("div", { className: overlayClass("historyTextBlock", "min-w-0 flex-1"), children: [
|
|
1423
|
+
/* @__PURE__ */ jsx3("p", { className: overlayClass("historyTimestamp", "truncate text-[10px] text-stone-700"), children: formatHistoryTime(item.createdAt) }),
|
|
1424
|
+
item.reason ? /* @__PURE__ */ jsx3("p", { className: overlayClass("historyReason", "truncate text-[10px] text-stone-500"), children: item.reason }) : null
|
|
1425
|
+
] }),
|
|
1426
|
+
/* @__PURE__ */ jsxs("div", { className: overlayClass("historyActions", "flex items-center gap-1"), children: [
|
|
1427
|
+
/* @__PURE__ */ jsx3(
|
|
1428
|
+
"button",
|
|
1176
1429
|
{
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1430
|
+
type: "button",
|
|
1431
|
+
disabled: deletingCheckpointId === item.id,
|
|
1432
|
+
className: overlayClass(
|
|
1433
|
+
"historyAction",
|
|
1434
|
+
"rounded border border-stone-300 bg-[#f7f2e8] px-1.5 py-0.5 text-[10px] text-stone-700 hover:bg-[#efe8dc] disabled:cursor-not-allowed disabled:opacity-50"
|
|
1435
|
+
),
|
|
1436
|
+
onClick: () => onRestoreCheckpoint(item),
|
|
1437
|
+
children: "Restore"
|
|
1182
1438
|
}
|
|
1183
|
-
)
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1439
|
+
),
|
|
1440
|
+
/* @__PURE__ */ jsx3(
|
|
1441
|
+
"button",
|
|
1442
|
+
{
|
|
1443
|
+
type: "button",
|
|
1444
|
+
"aria-label": "Delete checkpoint",
|
|
1445
|
+
title: "Delete checkpoint",
|
|
1446
|
+
disabled: deletingCheckpointId === item.id,
|
|
1447
|
+
className: overlayClass(
|
|
1448
|
+
"historyDelete",
|
|
1449
|
+
"inline-flex h-6 w-6 items-center justify-center rounded border border-stone-300 bg-[#f7f2e8] text-stone-700 hover:bg-[#efe8dc] disabled:cursor-not-allowed disabled:opacity-50"
|
|
1450
|
+
),
|
|
1451
|
+
onClick: () => onDeleteCheckpoint(item),
|
|
1452
|
+
children: /* @__PURE__ */ jsx3(
|
|
1453
|
+
"svg",
|
|
1454
|
+
{
|
|
1455
|
+
viewBox: "0 0 20 20",
|
|
1456
|
+
fill: "none",
|
|
1457
|
+
className: overlayClass("icon", "h-3.5 w-3.5"),
|
|
1458
|
+
"aria-hidden": "true",
|
|
1459
|
+
children: /* @__PURE__ */ jsx3(
|
|
1460
|
+
"path",
|
|
1461
|
+
{
|
|
1462
|
+
d: "M4.5 5.5H15.5M8 3.75H12M7 7.5V13.5M10 7.5V13.5M13 7.5V13.5M6.5 5.5L7 15C7.03 15.6 7.53 16.08 8.13 16.08H11.87C12.47 16.08 12.97 15.6 13 15L13.5 5.5",
|
|
1463
|
+
stroke: "currentColor",
|
|
1464
|
+
strokeWidth: "1.4",
|
|
1465
|
+
strokeLinecap: "round",
|
|
1466
|
+
strokeLinejoin: "round"
|
|
1467
|
+
}
|
|
1468
|
+
)
|
|
1469
|
+
}
|
|
1470
|
+
)
|
|
1471
|
+
}
|
|
1472
|
+
)
|
|
1473
|
+
] })
|
|
1474
|
+
]
|
|
1475
|
+
},
|
|
1476
|
+
`cp-${item.id}`
|
|
1477
|
+
)) }) : /* @__PURE__ */ jsx3("p", { className: overlayClass("emptyText", "text-[10px] text-stone-500"), children: "No checkpoints yet." }) })
|
|
1478
|
+
]
|
|
1479
|
+
}
|
|
1480
|
+
)
|
|
1192
1481
|
] }) });
|
|
1193
1482
|
}
|
|
1194
1483
|
function OverlayLauncherButton({ onOpen }) {
|
|
@@ -1197,13 +1486,74 @@ function OverlayLauncherButton({ onOpen }) {
|
|
|
1197
1486
|
{
|
|
1198
1487
|
type: "button",
|
|
1199
1488
|
onClick: onOpen,
|
|
1200
|
-
className:
|
|
1489
|
+
className: overlayClass(
|
|
1490
|
+
"launcherButton",
|
|
1491
|
+
"fixed bottom-4 right-4 z-[100] rounded-full border border-stone-600 bg-stone-700 px-4 py-2 text-[12px] font-semibold text-stone-100 shadow-xl hover:bg-stone-800"
|
|
1492
|
+
),
|
|
1201
1493
|
style: { fontFamily: OVERLAY_FONT_FAMILY },
|
|
1202
1494
|
children: "Chat to Webmaster"
|
|
1203
1495
|
}
|
|
1204
1496
|
);
|
|
1205
1497
|
}
|
|
1206
1498
|
|
|
1499
|
+
// src/overlay/core-styles.ts
|
|
1500
|
+
var OVERLAY_CORE_STYLE_ID = "wmd-core-styles";
|
|
1501
|
+
var OVERLAY_CORE_STYLE_TEXT = `
|
|
1502
|
+
.wmd-panel{position:fixed;right:1rem;bottom:1rem;z-index:100;display:flex;flex-direction:column;width:min(480px,calc(100vw - 1.5rem));height:62vh;max-height:calc(100vh - 1.5rem);overflow:hidden;box-sizing:border-box}
|
|
1503
|
+
.wmd-panel *{box-sizing:border-box}
|
|
1504
|
+
.wmd-launcher{position:fixed;right:1rem;bottom:1rem;z-index:100;box-sizing:border-box}
|
|
1505
|
+
.wmd-header{flex-shrink:0}
|
|
1506
|
+
.wmd-header-row{display:flex;align-items:center;gap:.5rem}
|
|
1507
|
+
.wmd-header-actions{margin-left:auto;display:flex;align-items:center;gap:.25rem}
|
|
1508
|
+
.wmd-tabs{display:inline-flex;align-items:center}
|
|
1509
|
+
.wmd-login-section{display:flex;flex:1;min-height:0;align-items:center;justify-content:center}
|
|
1510
|
+
.wmd-login-card,.wmd-login-warning{width:100%;max-width:24rem}
|
|
1511
|
+
.wmd-login-fields{display:flex;flex-direction:column;gap:.5rem}
|
|
1512
|
+
.wmd-chat-section{display:flex;flex:1;min-height:0;flex-direction:column;gap:.25rem;overflow:auto}
|
|
1513
|
+
.wmd-message--tool{max-width:96%}
|
|
1514
|
+
.wmd-message--user,.wmd-message--thinking,.wmd-message--assistant,.wmd-message--fallback{max-width:92%}
|
|
1515
|
+
.wmd-message--user{margin-left:auto}
|
|
1516
|
+
.wmd-message--assistant{position:relative}
|
|
1517
|
+
.wmd-assistant-avatar,.wmd-assistant-avatar-fallback{position:absolute;top:.375rem;left:.5rem;width:18px;height:18px}
|
|
1518
|
+
.wmd-assistant-avatar--pending{animation:wmd-pulse 2s cubic-bezier(.4,0,.6,1) infinite}
|
|
1519
|
+
.wmd-footer{flex-shrink:0}
|
|
1520
|
+
.wmd-model-row,.wmd-selected-element,.wmd-composer-row{display:flex;align-items:center;gap:.375rem}
|
|
1521
|
+
.wmd-model-select,.wmd-composer-input{min-width:0;flex:1}
|
|
1522
|
+
.wmd-composer-input{resize:none}
|
|
1523
|
+
.wmd-history-section{display:flex;flex:1;min-height:0;flex-direction:column}
|
|
1524
|
+
.wmd-history-columns{display:flex;flex:1;min-height:0;flex-direction:column;gap:.5rem;overflow:hidden}
|
|
1525
|
+
.wmd-history-card{display:flex;min-height:0;flex-direction:column}
|
|
1526
|
+
.wmd-history-list{overflow:auto}
|
|
1527
|
+
.wmd-history-stack{display:flex;flex-direction:column;gap:.25rem}
|
|
1528
|
+
.wmd-history-item{display:flex;align-items:center;justify-content:space-between;gap:.5rem}
|
|
1529
|
+
.wmd-history-item--checkpoint{display:flex;align-items:flex-start;justify-content:space-between;gap:.5rem}
|
|
1530
|
+
.wmd-history-text{min-width:0;flex:1}
|
|
1531
|
+
.wmd-history-actions{display:flex;align-items:center;gap:.25rem}
|
|
1532
|
+
.wmd-history-timestamp,.wmd-history-reason,.wmd-selected-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
1533
|
+
.wmd-icon-button,.wmd-selected-clear,.wmd-history-delete{display:inline-flex;align-items:center;justify-content:center}
|
|
1534
|
+
.wmd-icon{width:14px;height:14px}
|
|
1535
|
+
.wmd-selected-clear-icon{width:12px;height:12px}
|
|
1536
|
+
@media (max-width:640px){.wmd-panel{left:.75rem;right:.75rem;bottom:.75rem;width:auto;height:min(72vh,540px)}}
|
|
1537
|
+
@keyframes wmd-pulse{50%{opacity:.5}}
|
|
1538
|
+
`.trim();
|
|
1539
|
+
function ensureOverlayCoreStyles(doc) {
|
|
1540
|
+
const target = doc ?? (typeof document !== "undefined" ? document : void 0);
|
|
1541
|
+
if (!target) {
|
|
1542
|
+
return;
|
|
1543
|
+
}
|
|
1544
|
+
if (target.getElementById(OVERLAY_CORE_STYLE_ID)) {
|
|
1545
|
+
return;
|
|
1546
|
+
}
|
|
1547
|
+
const mountTarget = target.head ?? target.documentElement;
|
|
1548
|
+
if (!mountTarget) {
|
|
1549
|
+
return;
|
|
1550
|
+
}
|
|
1551
|
+
const styleElement = target.createElement("style");
|
|
1552
|
+
styleElement.id = OVERLAY_CORE_STYLE_ID;
|
|
1553
|
+
styleElement.textContent = OVERLAY_CORE_STYLE_TEXT;
|
|
1554
|
+
mountTarget.appendChild(styleElement);
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1207
1557
|
// src/overlay/controller.ts
|
|
1208
1558
|
import {
|
|
1209
1559
|
useCallback,
|
|
@@ -1634,8 +1984,14 @@ Reason: ${checkpoint.reason}` : "";
|
|
|
1634
1984
|
|
|
1635
1985
|
// src/overlay.tsx
|
|
1636
1986
|
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1637
|
-
function WebmasterDroidOverlay() {
|
|
1987
|
+
function WebmasterDroidOverlay({ injectCoreStyles = true }) {
|
|
1638
1988
|
const controller = useOverlayController();
|
|
1989
|
+
useEffect3(() => {
|
|
1990
|
+
if (!injectCoreStyles) {
|
|
1991
|
+
return;
|
|
1992
|
+
}
|
|
1993
|
+
ensureOverlayCoreStyles();
|
|
1994
|
+
}, [injectCoreStyles]);
|
|
1639
1995
|
if (!controller.isAdminMode) {
|
|
1640
1996
|
return null;
|
|
1641
1997
|
}
|
|
@@ -1644,7 +2000,10 @@ function WebmasterDroidOverlay() {
|
|
|
1644
2000
|
{
|
|
1645
2001
|
ref: controller.overlayRootRef,
|
|
1646
2002
|
"data-admin-overlay-root": true,
|
|
1647
|
-
className:
|
|
2003
|
+
className: overlayClass(
|
|
2004
|
+
"panel",
|
|
2005
|
+
"fixed bottom-4 right-4 z-[100] flex h-[62vh] w-[min(480px,calc(100vw-1.5rem))] flex-col overflow-hidden rounded-lg border border-stone-300 bg-[#f6f2eb] text-stone-900 shadow-2xl"
|
|
2006
|
+
),
|
|
1648
2007
|
style: { fontFamily: OVERLAY_FONT_FAMILY },
|
|
1649
2008
|
children: [
|
|
1650
2009
|
/* @__PURE__ */ jsx4(
|
|
@@ -1731,7 +2090,7 @@ function WebmasterDroidOverlay() {
|
|
|
1731
2090
|
import {
|
|
1732
2091
|
createContext as createContext3,
|
|
1733
2092
|
useContext as useContext3,
|
|
1734
|
-
useEffect as
|
|
2093
|
+
useEffect as useEffect4,
|
|
1735
2094
|
useMemo as useMemo3,
|
|
1736
2095
|
useState as useState3
|
|
1737
2096
|
} from "react";
|
|
@@ -1770,7 +2129,7 @@ function CmsRuntimeBridge(props) {
|
|
|
1770
2129
|
document: defaultDocument,
|
|
1771
2130
|
error: null
|
|
1772
2131
|
});
|
|
1773
|
-
|
|
2132
|
+
useEffect4(() => {
|
|
1774
2133
|
let ignore = false;
|
|
1775
2134
|
fetchCmsContent(config.apiBaseUrl, stage, token).then((content2) => {
|
|
1776
2135
|
if (ignore) {
|
|
@@ -1810,7 +2169,7 @@ function CmsRuntimeBridge(props) {
|
|
|
1810
2169
|
const content = props.applyThemeTokens ? /* @__PURE__ */ jsx5("div", { style: createThemeCssVariables(value.document.themeTokens), children: props.children }) : props.children;
|
|
1811
2170
|
return /* @__PURE__ */ jsxs3(CmsRuntimeContext.Provider, { value, children: [
|
|
1812
2171
|
/* @__PURE__ */ jsx5(EditableProvider, { document: value.document, mode: stage, enabled: isAdminMode, children: content }),
|
|
1813
|
-
props.includeOverlay ? /* @__PURE__ */ jsx5(WebmasterDroidOverlay, {}) : null
|
|
2172
|
+
props.includeOverlay ? /* @__PURE__ */ jsx5(WebmasterDroidOverlay, { injectCoreStyles: props.injectCoreStyles }) : null
|
|
1814
2173
|
] });
|
|
1815
2174
|
}
|
|
1816
2175
|
function WebmasterDroidRuntime(props) {
|
|
@@ -1820,6 +2179,7 @@ function WebmasterDroidRuntime(props) {
|
|
|
1820
2179
|
fallbackDocument: props.fallbackDocument,
|
|
1821
2180
|
includeOverlay: props.includeOverlay ?? true,
|
|
1822
2181
|
applyThemeTokens: props.applyThemeTokens ?? true,
|
|
2182
|
+
injectCoreStyles: props.injectCoreStyles ?? true,
|
|
1823
2183
|
children: props.children
|
|
1824
2184
|
}
|
|
1825
2185
|
) });
|