@alpaca-editor/core 1.0.4032 → 1.0.4037
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/components/index.d.ts +1 -0
- package/dist/components/index.js +1 -0
- package/dist/components/index.js.map +1 -1
- package/dist/{editor/menubar → components/ui}/LanguageSelector.d.ts +1 -1
- package/dist/{editor/menubar → components/ui}/LanguageSelector.js +8 -8
- package/dist/components/ui/LanguageSelector.js.map +1 -0
- package/dist/components/ui/button.d.ts +1 -1
- package/dist/components/ui/dropdown-menu.d.ts +1 -1
- package/dist/components/ui/dropdown-menu.js +2 -2
- package/dist/components/ui/dropdown-menu.js.map +1 -1
- package/dist/components/ui/sonner.js +3 -1
- package/dist/components/ui/sonner.js.map +1 -1
- package/dist/config/config.js +5 -5
- package/dist/config/config.js.map +1 -1
- package/dist/editor/ContentTree.d.ts +2 -1
- package/dist/editor/ContentTree.js +33 -9
- package/dist/editor/ContentTree.js.map +1 -1
- package/dist/editor/PictureEditor.js +2 -2
- package/dist/editor/PictureEditor.js.map +1 -1
- package/dist/editor/ScrollingContentTree.d.ts +2 -1
- package/dist/editor/ScrollingContentTree.js +2 -2
- package/dist/editor/ScrollingContentTree.js.map +1 -1
- package/dist/editor/Terminal.d.ts +2 -0
- package/dist/editor/Terminal.js +2 -2
- package/dist/editor/Terminal.js.map +1 -1
- package/dist/editor/ai/AgentHistory.d.ts +11 -0
- package/dist/editor/ai/AgentHistory.js +12 -0
- package/dist/editor/ai/AgentHistory.js.map +1 -0
- package/dist/editor/ai/Agents.js +187 -24
- package/dist/editor/ai/Agents.js.map +1 -1
- package/dist/editor/ai/AiResponseMessage.d.ts +2 -1
- package/dist/editor/ai/AiResponseMessage.js +6 -6
- package/dist/editor/ai/AiResponseMessage.js.map +1 -1
- package/dist/editor/ai/AiTerminal.d.ts +1 -0
- package/dist/editor/ai/AiTerminal.js +330 -43
- package/dist/editor/ai/AiTerminal.js.map +1 -1
- package/dist/editor/ai/aiPageModel.d.ts +2 -1
- package/dist/editor/ai/aiPageModel.js +56 -9
- package/dist/editor/ai/aiPageModel.js.map +1 -1
- package/dist/editor/client/itemsRepository.js +19 -7
- package/dist/editor/client/itemsRepository.js.map +1 -1
- package/dist/editor/field-types/InternalLinkFieldEditor.js +48 -1
- package/dist/editor/field-types/InternalLinkFieldEditor.js.map +1 -1
- package/dist/editor/field-types/richtext/contextMenuFactory.js +1 -1
- package/dist/editor/field-types/richtext/contextMenuFactory.js.map +1 -1
- package/dist/editor/menubar/ItemLanguageVersion.js +1 -1
- package/dist/editor/menubar/ItemLanguageVersion.js.map +1 -1
- package/dist/editor/menubar/PageSelector.js +1 -1
- package/dist/editor/menubar/PageSelector.js.map +1 -1
- package/dist/editor/page-editor-chrome/FieldActionIndicator.js +1 -1
- package/dist/editor/page-editor-chrome/FieldActionIndicator.js.map +1 -1
- package/dist/editor/page-editor-chrome/FieldEditedIndicator.js +2 -2
- package/dist/editor/page-editor-chrome/FieldEditedIndicator.js.map +1 -1
- package/dist/editor/page-editor-chrome/FrameMenu.js +2 -2
- package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
- package/dist/editor/page-editor-chrome/InlineEditor.js +9 -9
- package/dist/editor/page-editor-chrome/InlineEditor.js.map +1 -1
- package/dist/editor/page-editor-chrome/LockedFieldIndicator.js +2 -2
- package/dist/editor/page-editor-chrome/LockedFieldIndicator.js.map +1 -1
- package/dist/editor/page-editor-chrome/PageEditorChrome.js +1 -1
- package/dist/editor/page-editor-chrome/PageEditorChrome.js.map +1 -1
- package/dist/editor/page-editor-chrome/PictureEditorOverlay.js +1 -1
- package/dist/editor/page-editor-chrome/PictureEditorOverlay.js.map +1 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZone.js +1 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZones.js +2 -2
- package/dist/editor/page-editor-chrome/PlaceholderDropZones.js.map +1 -1
- package/dist/editor/page-editor-chrome/useInlineAICompletion.js +12 -12
- package/dist/editor/page-editor-chrome/useInlineAICompletion.js.map +1 -1
- package/dist/editor/page-viewer/EditorForm.js +1 -1
- package/dist/editor/page-viewer/EditorForm.js.map +1 -1
- package/dist/editor/page-viewer/MiniMap.js +10 -11
- package/dist/editor/page-viewer/MiniMap.js.map +1 -1
- package/dist/editor/page-viewer/PageViewer.js +2 -2
- package/dist/editor/page-viewer/PageViewer.js.map +1 -1
- package/dist/editor/page-viewer/PageViewerFrame.js +4 -4
- package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
- package/dist/editor/page-viewer/pageViewContext.d.ts +2 -2
- package/dist/editor/page-viewer/pageViewContext.js +11 -14
- package/dist/editor/page-viewer/pageViewContext.js.map +1 -1
- package/dist/editor/services/agentService.d.ts +21 -1
- package/dist/editor/services/agentService.js +101 -0
- package/dist/editor/services/agentService.js.map +1 -1
- package/dist/editor/services/aiService.d.ts +2 -1
- package/dist/editor/services/aiService.js +2 -4
- package/dist/editor/services/aiService.js.map +1 -1
- package/dist/editor/sidebar/GraphQL.js +5 -6
- package/dist/editor/sidebar/GraphQL.js.map +1 -1
- package/dist/editor/sidebar/MainContentTree.d.ts +2 -1
- package/dist/editor/sidebar/MainContentTree.js +9 -5
- package/dist/editor/sidebar/MainContentTree.js.map +1 -1
- package/dist/editor/ui/Icons.d.ts +5 -0
- package/dist/editor/ui/Icons.js +3 -0
- package/dist/editor/ui/Icons.js.map +1 -1
- package/dist/editor/ui/ItemNameDialogNew.js +26 -14
- package/dist/editor/ui/ItemNameDialogNew.js.map +1 -1
- package/dist/editor/ui/PerfectTree.js +54 -2
- package/dist/editor/ui/PerfectTree.js.map +1 -1
- package/dist/editor/views/CompareView.js +3 -3
- package/dist/editor/views/CompareView.js.map +1 -1
- package/dist/editor/views/EditView.js +1 -1
- package/dist/editor/views/EditView.js.map +1 -1
- package/dist/editor/views/ItemEditor.js +1 -1
- package/dist/editor/views/ItemEditor.js.map +1 -1
- package/dist/index.d.ts +3 -4
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/page-wizard/PageWizard.js +0 -5
- package/dist/page-wizard/PageWizard.js.map +1 -1
- package/dist/page-wizard/steps/ContentStep.js +39 -27
- package/dist/page-wizard/steps/ContentStep.js.map +1 -1
- package/dist/page-wizard/steps/FindItemsStep.js +2 -1
- package/dist/page-wizard/steps/FindItemsStep.js.map +1 -1
- package/dist/page-wizard/steps/ImagesStep.js +1 -1
- package/dist/page-wizard/steps/ImagesStep.js.map +1 -1
- package/dist/page-wizard/steps/LayoutStep.js +1 -1
- package/dist/page-wizard/steps/LayoutStep.js.map +1 -1
- package/dist/page-wizard/steps/MetaDataStep.js +1 -1
- package/dist/page-wizard/steps/MetaDataStep.js.map +1 -1
- package/dist/page-wizard/steps/SelectStep.js +1 -1
- package/dist/page-wizard/steps/StructureStep.js +32 -11
- package/dist/page-wizard/steps/StructureStep.js.map +1 -1
- package/dist/page-wizard/steps/TranslateStep.d.ts +1 -0
- package/dist/page-wizard/steps/TranslateStep.js +67 -73
- package/dist/page-wizard/steps/TranslateStep.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/splash-screen/NewPage.js +1 -1
- package/dist/splash-screen/NewPage.js.map +1 -1
- package/dist/splash-screen/OpenPage.js +1 -1
- package/dist/splash-screen/OpenPage.js.map +1 -1
- package/dist/styles.css +71 -8
- package/package.json +1 -1
- package/src/components/index.ts +1 -0
- package/src/{editor/menubar → components/ui}/LanguageSelector.tsx +12 -12
- package/src/components/ui/dropdown-menu.tsx +3 -1
- package/src/components/ui/sonner.tsx +5 -1
- package/src/config/config.tsx +4 -3
- package/src/editor/ContentTree.tsx +41 -12
- package/src/editor/PictureEditor.tsx +2 -2
- package/src/editor/ScrollingContentTree.tsx +3 -0
- package/src/editor/Terminal.tsx +16 -7
- package/src/editor/ai/AgentHistory.tsx +85 -0
- package/src/editor/ai/Agents.tsx +256 -88
- package/src/editor/ai/AiResponseMessage.tsx +25 -11
- package/src/editor/ai/AiTerminal.tsx +571 -73
- package/src/editor/ai/aiPageModel.ts +115 -6
- package/src/editor/client/itemsRepository.ts +29 -12
- package/src/editor/field-types/InternalLinkFieldEditor.tsx +53 -2
- package/src/editor/field-types/richtext/components/SimpleRichTextEditor.css +64 -0
- package/src/editor/field-types/richtext/contextMenuFactory.tsx +7 -8
- package/src/editor/menubar/ItemLanguageVersion.tsx +1 -1
- package/src/editor/menubar/PageSelector.tsx +1 -0
- package/src/editor/page-editor-chrome/FieldActionIndicator.tsx +1 -1
- package/src/editor/page-editor-chrome/FieldEditedIndicator.tsx +3 -3
- package/src/editor/page-editor-chrome/FrameMenu.tsx +2 -2
- package/src/editor/page-editor-chrome/InlineEditor.tsx +9 -12
- package/src/editor/page-editor-chrome/LockedFieldIndicator.tsx +3 -3
- package/src/editor/page-editor-chrome/PageEditorChrome.tsx +3 -3
- package/src/editor/page-editor-chrome/PictureEditorOverlay.tsx +1 -1
- package/src/editor/page-editor-chrome/PlaceholderDropZone.tsx +1 -1
- package/src/editor/page-editor-chrome/PlaceholderDropZones.tsx +2 -2
- package/src/editor/page-editor-chrome/useInlineAICompletion.tsx +12 -18
- package/src/editor/page-viewer/EditorForm.tsx +1 -1
- package/src/editor/page-viewer/MiniMap.tsx +10 -11
- package/src/editor/page-viewer/PageViewer.tsx +8 -3
- package/src/editor/page-viewer/PageViewerFrame.tsx +4 -4
- package/src/editor/page-viewer/pageViewContext.ts +71 -66
- package/src/editor/services/agentService.ts +129 -1
- package/src/editor/services/aiService.ts +5 -7
- package/src/editor/sidebar/GraphQL.tsx +16 -15
- package/src/editor/sidebar/MainContentTree.tsx +12 -4
- package/src/editor/ui/Icons.tsx +35 -0
- package/src/editor/ui/ItemNameDialogNew.tsx +29 -13
- package/src/editor/ui/PerfectTree.tsx +70 -4
- package/src/editor/views/CompareView.tsx +3 -3
- package/src/editor/views/EditView.tsx +1 -1
- package/src/editor/views/ItemEditor.tsx +1 -1
- package/src/index.ts +10 -4
- package/src/page-wizard/PageWizard.tsx +0 -12
- package/src/page-wizard/steps/ContentStep.tsx +46 -31
- package/src/page-wizard/steps/FindItemsStep.tsx +2 -1
- package/src/page-wizard/steps/ImagesStep.tsx +1 -1
- package/src/page-wizard/steps/LayoutStep.tsx +1 -1
- package/src/page-wizard/steps/MetaDataStep.tsx +1 -1
- package/src/page-wizard/steps/SelectStep.tsx +1 -1
- package/src/page-wizard/steps/StructureStep.tsx +45 -17
- package/src/page-wizard/steps/TranslateStep.tsx +326 -222
- package/src/revision.ts +2 -2
- package/src/splash-screen/NewPage.tsx +1 -0
- package/src/splash-screen/OpenPage.tsx +1 -0
- package/dist/components/SimpleLanguageSelector.d.ts +0 -10
- package/dist/components/SimpleLanguageSelector.js +0 -59
- package/dist/components/SimpleLanguageSelector.js.map +0 -1
- package/dist/editor/menubar/LanguageSelector.js.map +0 -1
- package/src/components/SimpleLanguageSelector.tsx +0 -113
|
@@ -59,8 +59,7 @@ export function useInlineAiCompletion({
|
|
|
59
59
|
isUpdatingRef.current = true;
|
|
60
60
|
|
|
61
61
|
try {
|
|
62
|
-
const iframeWindow =
|
|
63
|
-
pageViewContext.editorIframeRef.current?.contentWindow;
|
|
62
|
+
const iframeWindow = pageViewContext.editorIframe?.contentWindow;
|
|
64
63
|
const iframeDocument = iframeWindow?.document;
|
|
65
64
|
const editableElement = editContext?.inlineEditingFieldElement;
|
|
66
65
|
|
|
@@ -174,7 +173,7 @@ export function useInlineAiCompletion({
|
|
|
174
173
|
if (e.key === "ArrowRight" || e.key === "Delete") {
|
|
175
174
|
// Make sure the cursor span doesn't block the movement/deletion
|
|
176
175
|
const cursorSpan =
|
|
177
|
-
pageViewContext.
|
|
176
|
+
pageViewContext.editorIframe?.contentWindow?.document.getElementById(
|
|
178
177
|
cursorSpanId,
|
|
179
178
|
);
|
|
180
179
|
if (cursorSpan) {
|
|
@@ -193,12 +192,12 @@ export function useInlineAiCompletion({
|
|
|
193
192
|
}
|
|
194
193
|
};
|
|
195
194
|
|
|
196
|
-
pageViewContext.
|
|
195
|
+
pageViewContext.editorIframe?.contentWindow?.document.addEventListener(
|
|
197
196
|
"keydown",
|
|
198
197
|
keyHandler,
|
|
199
198
|
);
|
|
200
199
|
return () => {
|
|
201
|
-
pageViewContext.
|
|
200
|
+
pageViewContext.editorIframe?.contentWindow?.document.removeEventListener(
|
|
202
201
|
"keydown",
|
|
203
202
|
keyHandler,
|
|
204
203
|
);
|
|
@@ -207,7 +206,7 @@ export function useInlineAiCompletion({
|
|
|
207
206
|
|
|
208
207
|
// Extracts the text up to the cursor position in the editable element
|
|
209
208
|
const getContentUpToCursor = (element: HTMLElement) => {
|
|
210
|
-
const iframeWindow = pageViewContext.
|
|
209
|
+
const iframeWindow = pageViewContext.editorIframe?.contentWindow;
|
|
211
210
|
const selection = iframeWindow?.getSelection();
|
|
212
211
|
if (!element || !selection || selection.rangeCount === 0) return null;
|
|
213
212
|
const range = selection.getRangeAt(0);
|
|
@@ -235,8 +234,7 @@ export function useInlineAiCompletion({
|
|
|
235
234
|
|
|
236
235
|
// Loading animation with three dots changing color
|
|
237
236
|
const startLoadingAnimation = () => {
|
|
238
|
-
const doc =
|
|
239
|
-
pageViewContext.editorIframeRef.current?.contentWindow?.document;
|
|
237
|
+
const doc = pageViewContext.editorIframe?.contentWindow?.document;
|
|
240
238
|
const span = doc?.getElementById(cursorSpanId);
|
|
241
239
|
if (!doc || !span) return;
|
|
242
240
|
|
|
@@ -456,8 +454,7 @@ ONLY provide the completion text (what comes after the user's text), never repea
|
|
|
456
454
|
|
|
457
455
|
// Inserts or clears the ghost text inside the cursor span
|
|
458
456
|
const updateCursorSpan = (text: string) => {
|
|
459
|
-
const doc =
|
|
460
|
-
pageViewContext.editorIframeRef.current?.contentWindow?.document;
|
|
457
|
+
const doc = pageViewContext.editorIframe?.contentWindow?.document;
|
|
461
458
|
const span = doc?.getElementById(cursorSpanId);
|
|
462
459
|
if (!doc || !span) return;
|
|
463
460
|
|
|
@@ -510,8 +507,7 @@ ONLY provide the completion text (what comes after the user's text), never repea
|
|
|
510
507
|
});
|
|
511
508
|
|
|
512
509
|
// Position the hint element relative to the iframe and cursor span
|
|
513
|
-
const iframeRect =
|
|
514
|
-
pageViewContext.editorIframeRef.current?.getBoundingClientRect();
|
|
510
|
+
const iframeRect = pageViewContext.editorIframe?.getBoundingClientRect();
|
|
515
511
|
const spanRect = span.getBoundingClientRect();
|
|
516
512
|
|
|
517
513
|
if (iframeRect) {
|
|
@@ -550,8 +546,7 @@ ONLY provide the completion text (what comes after the user's text), never repea
|
|
|
550
546
|
};
|
|
551
547
|
|
|
552
548
|
const clearCursorSpan = () => {
|
|
553
|
-
const doc =
|
|
554
|
-
pageViewContext.editorIframeRef.current?.contentWindow?.document;
|
|
549
|
+
const doc = pageViewContext.editorIframe?.contentWindow?.document;
|
|
555
550
|
if (!doc) return;
|
|
556
551
|
|
|
557
552
|
// Clear the completion text
|
|
@@ -587,7 +582,7 @@ ONLY provide the completion text (what comes after the user's text), never repea
|
|
|
587
582
|
if (e.key === "Tab") {
|
|
588
583
|
// Check if there's an actual completion in the cursor span
|
|
589
584
|
const cursorSpan =
|
|
590
|
-
pageViewContext.
|
|
585
|
+
pageViewContext.editorIframe?.contentWindow?.document.getElementById(
|
|
591
586
|
cursorSpanId,
|
|
592
587
|
);
|
|
593
588
|
if (
|
|
@@ -632,8 +627,7 @@ ONLY provide the completion text (what comes after the user's text), never repea
|
|
|
632
627
|
const el = editContext?.inlineEditingFieldElement;
|
|
633
628
|
if (!el) return false;
|
|
634
629
|
|
|
635
|
-
const iframeWindow =
|
|
636
|
-
pageViewContext.editorIframeRef.current?.contentWindow;
|
|
630
|
+
const iframeWindow = pageViewContext.editorIframe?.contentWindow;
|
|
637
631
|
const selection = iframeWindow?.getSelection();
|
|
638
632
|
if (!selection || selection.rangeCount === 0) return false;
|
|
639
633
|
|
|
@@ -729,7 +723,7 @@ ONLY provide the completion text (what comes after the user's text), never repea
|
|
|
729
723
|
// Function to apply the completion
|
|
730
724
|
const applyCompletion = () => {
|
|
731
725
|
// Get the cursor span to read the most up-to-date completion
|
|
732
|
-
const iframeWindow = pageViewContext.
|
|
726
|
+
const iframeWindow = pageViewContext.editorIframe?.contentWindow;
|
|
733
727
|
const iframeDocument = iframeWindow?.document;
|
|
734
728
|
if (
|
|
735
729
|
!iframeWindow ||
|
|
@@ -392,7 +392,7 @@ export function EditorForm({
|
|
|
392
392
|
<SimpleTabs
|
|
393
393
|
key="editor-tabs"
|
|
394
394
|
tabs={tabPanels}
|
|
395
|
-
className="flex
|
|
395
|
+
className="flex items-center justify-center border-b border-gray-200 pt-4 text-xs"
|
|
396
396
|
activeTab={tabPanels.findIndex((x) => x.id === activeTabKey) || 0}
|
|
397
397
|
setActiveTab={(index) => setActiveTabKey(tabPanels[index]?.id!)}
|
|
398
398
|
></SimpleTabs>
|
|
@@ -31,14 +31,13 @@ export function MiniMap({
|
|
|
31
31
|
|
|
32
32
|
const observerRef = useRef<MutationObserver | null>(null);
|
|
33
33
|
|
|
34
|
-
const editorIframeRef = mainViewIframeRef;
|
|
35
34
|
const minimapContainerRef = useRef<HTMLDivElement>(null);
|
|
36
35
|
|
|
37
36
|
if (!mainViewIframeRef.current) return;
|
|
38
37
|
|
|
39
38
|
const scrollContainer =
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
mainViewIframeRef.current?.contentWindow?.document.scrollingElement ||
|
|
40
|
+
mainViewIframeRef.current?.contentWindow?.document.body;
|
|
42
41
|
|
|
43
42
|
const calcAndUpdateScale = () => {
|
|
44
43
|
const viewport = pageViewContext.viewport;
|
|
@@ -139,7 +138,7 @@ export function MiniMap({
|
|
|
139
138
|
const handleLoad = () => {
|
|
140
139
|
if (!mainViewIframeRef?.current?.contentWindow?.document) return;
|
|
141
140
|
|
|
142
|
-
mirrorIframeContent(
|
|
141
|
+
mirrorIframeContent(mainViewIframeRef.current!, iframeRef.current!);
|
|
143
142
|
|
|
144
143
|
const observer = new MutationObserver((mutationsList) => {
|
|
145
144
|
const minimapDoc = iframeRef.current?.contentDocument;
|
|
@@ -197,15 +196,15 @@ export function MiniMap({
|
|
|
197
196
|
};
|
|
198
197
|
|
|
199
198
|
useEffect(() => {
|
|
200
|
-
if (
|
|
201
|
-
|
|
199
|
+
if (mainViewIframeRef?.current) {
|
|
200
|
+
mainViewIframeRef?.current.addEventListener("load", handleLoad);
|
|
202
201
|
}
|
|
203
202
|
|
|
204
203
|
handleLoad();
|
|
205
204
|
|
|
206
205
|
// Cleanup function
|
|
207
206
|
return () => {
|
|
208
|
-
|
|
207
|
+
mainViewIframeRef?.current?.removeEventListener("load", handleLoad);
|
|
209
208
|
};
|
|
210
209
|
}, [mainViewIframeRef.current, iframeRef.current]);
|
|
211
210
|
|
|
@@ -213,7 +212,7 @@ export function MiniMap({
|
|
|
213
212
|
calcAndUpdateScale();
|
|
214
213
|
}, [
|
|
215
214
|
refreshScale,
|
|
216
|
-
|
|
215
|
+
mainViewIframeRef,
|
|
217
216
|
//pageViewContext?.windowSize,
|
|
218
217
|
pageViewContext?.zoom,
|
|
219
218
|
pageViewContext.viewport,
|
|
@@ -226,7 +225,7 @@ export function MiniMap({
|
|
|
226
225
|
}
|
|
227
226
|
|
|
228
227
|
const scrollDocumentTo = (y: number) => {
|
|
229
|
-
if (!
|
|
228
|
+
if (!mainViewIframeRef?.current) return;
|
|
230
229
|
|
|
231
230
|
if (!scrollContainer) return;
|
|
232
231
|
|
|
@@ -289,7 +288,7 @@ export function MiniMap({
|
|
|
289
288
|
left: 0,
|
|
290
289
|
top: e.deltaY,
|
|
291
290
|
});
|
|
292
|
-
|
|
291
|
+
mainViewIframeRef.current?.contentWindow?.document.documentElement?.scrollBy(
|
|
293
292
|
{
|
|
294
293
|
behavior: "instant",
|
|
295
294
|
left: 0,
|
|
@@ -298,7 +297,7 @@ export function MiniMap({
|
|
|
298
297
|
);
|
|
299
298
|
e.stopPropagation();
|
|
300
299
|
},
|
|
301
|
-
[
|
|
300
|
+
[mainViewIframeRef],
|
|
302
301
|
);
|
|
303
302
|
|
|
304
303
|
return (
|
|
@@ -3,7 +3,10 @@ import { EditorForm } from "./EditorForm";
|
|
|
3
3
|
import { PageViewerFrame } from "./PageViewerFrame";
|
|
4
4
|
import { useEffect, useState } from "react";
|
|
5
5
|
import { SimpleIconButton } from "../ui/SimpleIconButton";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
useEditContext,
|
|
8
|
+
useModifiedFieldsContext,
|
|
9
|
+
} from "../client/editContext";
|
|
7
10
|
import { PanelLeftClose, PanelLeftOpen } from "lucide-react";
|
|
8
11
|
import { cn } from "../../lib/utils";
|
|
9
12
|
import { Splitter, SplitterPanel } from "../ui/Splitter";
|
|
@@ -50,7 +53,9 @@ export function PageViewer({
|
|
|
50
53
|
if (editContext?.inlineEditingFieldElement) return;
|
|
51
54
|
|
|
52
55
|
const lastEdit =
|
|
53
|
-
modifiedFieldsContext.recentEdits[
|
|
56
|
+
modifiedFieldsContext.recentEdits[
|
|
57
|
+
modifiedFieldsContext.recentEdits.length - 1
|
|
58
|
+
];
|
|
54
59
|
|
|
55
60
|
if (!lastEdit) return;
|
|
56
61
|
|
|
@@ -62,7 +67,7 @@ export function PageViewer({
|
|
|
62
67
|
}
|
|
63
68
|
|
|
64
69
|
const element =
|
|
65
|
-
pageViewContext?.
|
|
70
|
+
pageViewContext?.editorIframe?.contentWindow?.document.querySelector(
|
|
66
71
|
`[data-fieldid="${lastEdit.fieldId}"][data-itemid="${lastEdit.item.id}"][data-language="${lastEdit.item.language}"][data-version="${lastEdit.item.version}"]`,
|
|
67
72
|
);
|
|
68
73
|
|
|
@@ -62,7 +62,7 @@ export function PageViewerFrame({
|
|
|
62
62
|
|
|
63
63
|
const editContextRef = useEditContextRef();
|
|
64
64
|
|
|
65
|
-
const iframeRef =
|
|
65
|
+
const iframeRef = useRef<HTMLIFrameElement | null>(null);
|
|
66
66
|
|
|
67
67
|
const [showSpinner, setShowSpinner] = useState(false);
|
|
68
68
|
const [scroll, setScroll] = useState(0);
|
|
@@ -118,10 +118,10 @@ export function PageViewerFrame({
|
|
|
118
118
|
|
|
119
119
|
const pageItemDescriptor = pageViewContext.pageItemDescriptor;
|
|
120
120
|
|
|
121
|
+
// Update the context whenever the iframe ref changes
|
|
121
122
|
useEffect(() => {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}, [iframeRef.current]);
|
|
123
|
+
pageViewContext.setEditorIframe(iframeRef.current);
|
|
124
|
+
}, [iframeRef.current, pageViewContext.setEditorIframe]);
|
|
125
125
|
|
|
126
126
|
const updateMiniMapVisibility = useDebouncedCallback(() => {
|
|
127
127
|
if (!iframeRef.current) return;
|
|
@@ -17,7 +17,10 @@ export type PageViewContext = {
|
|
|
17
17
|
setScroll: React.Dispatch<React.SetStateAction<number>>;
|
|
18
18
|
fullscreen: boolean;
|
|
19
19
|
setFullscreen: React.Dispatch<React.SetStateAction<boolean>>;
|
|
20
|
-
|
|
20
|
+
editorIframe: HTMLIFrameElement | null;
|
|
21
|
+
setEditorIframe: React.Dispatch<
|
|
22
|
+
React.SetStateAction<HTMLIFrameElement | null>
|
|
23
|
+
>;
|
|
21
24
|
deviceWidth?: number;
|
|
22
25
|
deviceHeight?: number;
|
|
23
26
|
setDeviceWidth: React.Dispatch<React.SetStateAction<number | undefined>>;
|
|
@@ -32,7 +35,6 @@ export type PageViewContext = {
|
|
|
32
35
|
React.SetStateAction<PageSkeleton | undefined>
|
|
33
36
|
>;
|
|
34
37
|
viewport: { width: number; height: number };
|
|
35
|
-
setWorkaround: React.Dispatch<React.SetStateAction<boolean>>;
|
|
36
38
|
isHeadless: boolean;
|
|
37
39
|
site?: Site;
|
|
38
40
|
editUrl?: string;
|
|
@@ -52,13 +54,14 @@ export function usePageViewContext({
|
|
|
52
54
|
const [zoom, setZoom] = useState<number>(1);
|
|
53
55
|
const [scroll, setScroll] = useState<number>(0);
|
|
54
56
|
const [fullscreen, setFullscreen] = useState<boolean>(false);
|
|
55
|
-
const
|
|
57
|
+
const [editorIframe, setEditorIframe] = useState<HTMLIFrameElement | null>(
|
|
58
|
+
null,
|
|
59
|
+
);
|
|
56
60
|
const [deviceWidth, setDeviceWidth] = useState<number>();
|
|
57
61
|
const [deviceHeight, setDeviceHeight] = useState<number>();
|
|
58
62
|
const [lockHeight, setLockHeight] = useState(true);
|
|
59
63
|
const [rotate, setRotate] = useState(false);
|
|
60
64
|
const [viewportRect, setViewportRect] = useState({ width: 0, height: 0 });
|
|
61
|
-
const [workaround, setWorkaround] = useState(false);
|
|
62
65
|
const [site, setSite] = useState<Site>();
|
|
63
66
|
const [resolvedPageItemDescriptor, setResolvedPageItemDescriptor] =
|
|
64
67
|
useState<ItemDescriptor>();
|
|
@@ -100,17 +103,15 @@ export function usePageViewContext({
|
|
|
100
103
|
updateViewportRectDebounced();
|
|
101
104
|
});
|
|
102
105
|
|
|
103
|
-
if (
|
|
104
|
-
resizeObserver.observe(
|
|
106
|
+
if (editorIframe) {
|
|
107
|
+
resizeObserver.observe(editorIframe);
|
|
105
108
|
}
|
|
106
109
|
|
|
107
110
|
// Cleanup function
|
|
108
111
|
return () => {
|
|
109
|
-
|
|
110
|
-
resizeObserver.disconnect();
|
|
111
|
-
}
|
|
112
|
+
resizeObserver.disconnect();
|
|
112
113
|
};
|
|
113
|
-
}, [
|
|
114
|
+
}, [editorIframe, updateViewportRectDebounced]);
|
|
114
115
|
|
|
115
116
|
useEffect(() => {
|
|
116
117
|
if (!pageItemDescriptor) return;
|
|
@@ -161,7 +162,8 @@ export function usePageViewContext({
|
|
|
161
162
|
}, [pageItemDescriptor]);
|
|
162
163
|
|
|
163
164
|
function updateViewportRect() {
|
|
164
|
-
const rect =
|
|
165
|
+
const rect = editorIframe?.getBoundingClientRect();
|
|
166
|
+
|
|
165
167
|
if (rect) {
|
|
166
168
|
setViewportRect((prev) => {
|
|
167
169
|
// Only update if dimensions actually changed
|
|
@@ -173,61 +175,64 @@ export function usePageViewContext({
|
|
|
173
175
|
}
|
|
174
176
|
}
|
|
175
177
|
|
|
176
|
-
const pageViewContext: PageViewContext = useMemo(
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
178
|
+
const pageViewContext: PageViewContext = useMemo(
|
|
179
|
+
() => ({
|
|
180
|
+
device,
|
|
181
|
+
setDevice,
|
|
182
|
+
deviceWidth,
|
|
183
|
+
setDeviceWidth,
|
|
184
|
+
deviceHeight,
|
|
185
|
+
setDeviceHeight,
|
|
186
|
+
lockHeight,
|
|
187
|
+
setLockHeight,
|
|
188
|
+
scroll,
|
|
189
|
+
setScroll,
|
|
190
|
+
zoom,
|
|
191
|
+
setZoom,
|
|
192
|
+
fullscreen,
|
|
193
|
+
setFullscreen,
|
|
194
|
+
editorIframe,
|
|
195
|
+
setEditorIframe,
|
|
196
|
+
rotate,
|
|
197
|
+
setRotate,
|
|
198
|
+
page,
|
|
199
|
+
setPageSkeleton,
|
|
200
|
+
viewport: viewportRect,
|
|
201
|
+
pageItemDescriptor: resolvedPageItemDescriptor,
|
|
202
|
+
isHeadless,
|
|
203
|
+
site,
|
|
204
|
+
editUrl,
|
|
205
|
+
previewUrl,
|
|
206
|
+
}),
|
|
207
|
+
[
|
|
208
|
+
device,
|
|
209
|
+
deviceWidth,
|
|
210
|
+
deviceHeight,
|
|
211
|
+
lockHeight,
|
|
212
|
+
scroll,
|
|
213
|
+
zoom,
|
|
214
|
+
fullscreen,
|
|
215
|
+
rotate,
|
|
216
|
+
page,
|
|
217
|
+
viewportRect,
|
|
218
|
+
resolvedPageItemDescriptor,
|
|
219
|
+
isHeadless,
|
|
220
|
+
site,
|
|
221
|
+
editUrl,
|
|
222
|
+
previewUrl,
|
|
223
|
+
setDevice,
|
|
224
|
+
setDeviceWidth,
|
|
225
|
+
setDeviceHeight,
|
|
226
|
+
setLockHeight,
|
|
227
|
+
setScroll,
|
|
228
|
+
setZoom,
|
|
229
|
+
setFullscreen,
|
|
230
|
+
setRotate,
|
|
231
|
+
setPageSkeleton,
|
|
232
|
+
editorIframe,
|
|
233
|
+
setEditorIframe,
|
|
234
|
+
],
|
|
235
|
+
);
|
|
231
236
|
|
|
232
237
|
return pageViewContext;
|
|
233
238
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AiContext } from "../ai/AiTerminal";
|
|
1
|
+
import { AiContext, Message } from "../ai/AiTerminal";
|
|
2
2
|
|
|
3
3
|
export const AGENT_BASE_URL = "/alpaca/editor/agent";
|
|
4
4
|
|
|
@@ -297,6 +297,13 @@ async function processEventStream(
|
|
|
297
297
|
}
|
|
298
298
|
} catch (error) {
|
|
299
299
|
console.error("Failed to parse SSE message:", error, line);
|
|
300
|
+
// Send error message to the client to notify user
|
|
301
|
+
onMessage({
|
|
302
|
+
type: AgentStreamMessageType.Error,
|
|
303
|
+
error: `Failed to parse stream message: ${error instanceof Error ? error.message : "Unknown parsing error"}`,
|
|
304
|
+
data: null,
|
|
305
|
+
timestamp: new Date().toISOString(),
|
|
306
|
+
});
|
|
300
307
|
}
|
|
301
308
|
}
|
|
302
309
|
}
|
|
@@ -466,3 +473,124 @@ export async function cancelAgent(
|
|
|
466
473
|
|
|
467
474
|
return await response.json();
|
|
468
475
|
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Permanently deletes an agent and all its messages
|
|
479
|
+
*/
|
|
480
|
+
export async function deleteAgent(
|
|
481
|
+
agentId: string,
|
|
482
|
+
context: AiContext,
|
|
483
|
+
): Promise<any> {
|
|
484
|
+
const response = await fetch(AGENT_BASE_URL + "/deleteAgent", {
|
|
485
|
+
method: "POST",
|
|
486
|
+
headers: {
|
|
487
|
+
"Content-Type": "application/json",
|
|
488
|
+
},
|
|
489
|
+
body: JSON.stringify({ agentId }),
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
if (!response.ok) {
|
|
493
|
+
throw new Error(
|
|
494
|
+
`Failed to delete agent: ${response.status} ${response.statusText}`,
|
|
495
|
+
);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
return await response.json();
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* Closes an agent by canceling execution and setting status to closed
|
|
503
|
+
*/
|
|
504
|
+
export async function closeAgent(
|
|
505
|
+
agentId: string,
|
|
506
|
+
context: AiContext,
|
|
507
|
+
): Promise<any> {
|
|
508
|
+
const response = await fetch(AGENT_BASE_URL + "/closeAgent", {
|
|
509
|
+
method: "POST",
|
|
510
|
+
headers: {
|
|
511
|
+
"Content-Type": "application/json",
|
|
512
|
+
},
|
|
513
|
+
body: JSON.stringify({ agentId }),
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
if (!response.ok) {
|
|
517
|
+
throw new Error(
|
|
518
|
+
`Failed to close agent: ${response.status} ${response.statusText}`,
|
|
519
|
+
);
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
return await response.json();
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* Checks if an agent exists and returns its current state with messages
|
|
527
|
+
*/
|
|
528
|
+
export async function checkAgentState(
|
|
529
|
+
agentId: string,
|
|
530
|
+
context: AiContext,
|
|
531
|
+
): Promise<{ exists: boolean; agent?: AgentChat; isRunning: boolean }> {
|
|
532
|
+
try {
|
|
533
|
+
const agent = await getAgent(agentId, context);
|
|
534
|
+
return {
|
|
535
|
+
exists: true,
|
|
536
|
+
agent,
|
|
537
|
+
isRunning: agent.status === "Active",
|
|
538
|
+
};
|
|
539
|
+
} catch (error) {
|
|
540
|
+
// If agent doesn't exist, return false
|
|
541
|
+
return {
|
|
542
|
+
exists: false,
|
|
543
|
+
isRunning: false,
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Converts persisted agent messages to the format expected by AiTerminal
|
|
550
|
+
*/
|
|
551
|
+
export function convertAgentMessagesToTerminalFormat(
|
|
552
|
+
agentMessages: AgentChatMessage[],
|
|
553
|
+
): Message[] {
|
|
554
|
+
const terminalMessages: Message[] = [];
|
|
555
|
+
|
|
556
|
+
for (const agentMessage of agentMessages) {
|
|
557
|
+
// Convert assistant and user messages
|
|
558
|
+
if (agentMessage.role === "assistant" || agentMessage.role === "user") {
|
|
559
|
+
const terminalMessage: Message = {
|
|
560
|
+
id: agentMessage.id,
|
|
561
|
+
content: agentMessage.content,
|
|
562
|
+
name: agentMessage.name,
|
|
563
|
+
role: agentMessage.role,
|
|
564
|
+
tool_calls: [],
|
|
565
|
+
};
|
|
566
|
+
|
|
567
|
+
// Add tool calls if they exist
|
|
568
|
+
if (agentMessage.toolCalls && agentMessage.toolCalls.length > 0) {
|
|
569
|
+
terminalMessage.tool_calls = agentMessage.toolCalls.map((tc) => ({
|
|
570
|
+
id: tc.toolCallId,
|
|
571
|
+
displayName: tc.functionName,
|
|
572
|
+
function: {
|
|
573
|
+
name: tc.functionName,
|
|
574
|
+
arguments: tc.functionArguments,
|
|
575
|
+
},
|
|
576
|
+
}));
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
terminalMessages.push(terminalMessage);
|
|
580
|
+
}
|
|
581
|
+
// Convert tool result messages
|
|
582
|
+
else if (agentMessage.role === "tool") {
|
|
583
|
+
const terminalMessage: Message = {
|
|
584
|
+
id: agentMessage.id,
|
|
585
|
+
content: agentMessage.content,
|
|
586
|
+
name: agentMessage.name,
|
|
587
|
+
role: agentMessage.role,
|
|
588
|
+
tool_call_id: agentMessage.toolCallId,
|
|
589
|
+
};
|
|
590
|
+
|
|
591
|
+
terminalMessages.push(terminalMessage);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
return terminalMessages;
|
|
596
|
+
}
|
|
@@ -14,7 +14,7 @@ export type AiProfile = {
|
|
|
14
14
|
id: string;
|
|
15
15
|
name: string;
|
|
16
16
|
instructions: string;
|
|
17
|
-
|
|
17
|
+
defaultModelId: string | null; // Guid as string, nullable
|
|
18
18
|
models: AiModel[]; // Array of model objects with id and name
|
|
19
19
|
prompts: { prompt: string; title: string }[];
|
|
20
20
|
errorMessage?: string;
|
|
@@ -87,6 +87,7 @@ export interface ExecutePromptOptions {
|
|
|
87
87
|
addContextContent?: boolean;
|
|
88
88
|
addAllContent?: boolean;
|
|
89
89
|
profile?: string;
|
|
90
|
+
endpoint?: string;
|
|
90
91
|
}
|
|
91
92
|
|
|
92
93
|
// Unified function signature
|
|
@@ -103,7 +104,6 @@ export async function executePrompt(
|
|
|
103
104
|
callback?: (response: any) => void,
|
|
104
105
|
stream?: boolean,
|
|
105
106
|
): Promise<ExecutePromptResponse | null> {
|
|
106
|
-
let endpoint: string;
|
|
107
107
|
let requestBody: any;
|
|
108
108
|
let finalRequestOptions: RequestInit;
|
|
109
109
|
|
|
@@ -121,9 +121,6 @@ export async function executePrompt(
|
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
// Use hardcoded endpoint for old prompt system
|
|
125
|
-
endpoint = "/alpaca/editor/ai/Prompt";
|
|
126
|
-
|
|
127
124
|
// Build unified request body
|
|
128
125
|
requestBody = {
|
|
129
126
|
messages,
|
|
@@ -135,8 +132,6 @@ export async function executePrompt(
|
|
|
135
132
|
...options,
|
|
136
133
|
};
|
|
137
134
|
|
|
138
|
-
console.log("ExecutePrompt: requestBody", requestBody);
|
|
139
|
-
|
|
140
135
|
finalRequestOptions = {
|
|
141
136
|
method: "POST",
|
|
142
137
|
body: JSON.stringify(requestBody),
|
|
@@ -147,6 +142,9 @@ export async function executePrompt(
|
|
|
147
142
|
...requestOptions,
|
|
148
143
|
};
|
|
149
144
|
|
|
145
|
+
// Use hardcoded endpoint for old prompt system
|
|
146
|
+
const endpoint = options.endpoint || "/alpaca/editor/ai/prompt";
|
|
147
|
+
|
|
150
148
|
const response = await fetch(endpoint, finalRequestOptions);
|
|
151
149
|
|
|
152
150
|
if (!response.ok) {
|
|
@@ -258,21 +258,22 @@ export function GraphQL() {
|
|
|
258
258
|
<Splitter layout="horizontal" style={{ height: "100%" }}>
|
|
259
259
|
<SplitterPanel size={50} className="relative">
|
|
260
260
|
<div className="absolute inset-0 flex items-stretch">
|
|
261
|
-
<div className="min-w-0 flex-1">
|
|
262
|
-
<
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
261
|
+
<div className="relative min-w-0 flex-1">
|
|
262
|
+
<div className="absolute inset-0 overflow-auto">
|
|
263
|
+
<CodeEditor
|
|
264
|
+
value={query}
|
|
265
|
+
language="graphql"
|
|
266
|
+
placeholder="Enter your GraphQL query here..."
|
|
267
|
+
onChange={(evn: any) => setQuery(evn.target.value)}
|
|
268
|
+
padding={15}
|
|
269
|
+
style={{
|
|
270
|
+
fontSize: 12,
|
|
271
|
+
backgroundColor: "#f8f9fa",
|
|
272
|
+
fontFamily:
|
|
273
|
+
"ui-monospace,SFMono-Regular,SF Mono,Consolas,Liberation Mono,Menlo,monospace",
|
|
274
|
+
}}
|
|
275
|
+
/>
|
|
276
|
+
</div>
|
|
276
277
|
</div>
|
|
277
278
|
<ActionButton
|
|
278
279
|
onClick={refresh}
|