@alpaca-editor/core 1.0.4103 → 1.0.4104
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/ui/context-menu.d.ts +1 -1
- package/dist/components/ui/context-menu.js +8 -8
- package/dist/components/ui/context-menu.js.map +1 -1
- package/dist/config/config.js +8 -1
- package/dist/config/config.js.map +1 -1
- package/dist/config/types.d.ts +1 -0
- package/dist/editor/ContentTree.js +15 -16
- package/dist/editor/ContentTree.js.map +1 -1
- package/dist/editor/ContextMenu.js +37 -6
- package/dist/editor/ContextMenu.js.map +1 -1
- package/dist/editor/MainLayout.js +1 -1
- package/dist/editor/MainLayout.js.map +1 -1
- package/dist/editor/ai/AgentHistory.js +1 -1
- package/dist/editor/ai/AgentTerminal.js +187 -13
- package/dist/editor/ai/AgentTerminal.js.map +1 -1
- package/dist/editor/ai/AiResponseMessage.d.ts +1 -1
- package/dist/editor/ai/types.d.ts +25 -0
- package/dist/editor/ai/types.js +2 -0
- package/dist/editor/ai/types.js.map +1 -0
- package/dist/editor/client/EditorShell.js +29 -0
- package/dist/editor/client/EditorShell.js.map +1 -1
- package/dist/editor/client/editContext.d.ts +3 -0
- package/dist/editor/client/editContext.js.map +1 -1
- package/dist/editor/commands/agentCommands.d.ts +9 -0
- package/dist/editor/commands/agentCommands.js +30 -0
- package/dist/editor/commands/agentCommands.js.map +1 -0
- package/dist/editor/commands/itemCommands.js +14 -14
- package/dist/editor/commands/itemCommands.js.map +1 -1
- package/dist/editor/component-designer/aiContext.d.ts +1 -1
- package/dist/editor/context-menu/InsertMenu.d.ts +2 -1
- package/dist/editor/context-menu/InsertMenu.js +20 -15
- package/dist/editor/context-menu/InsertMenu.js.map +1 -1
- package/dist/editor/field-types/NameValueListEditor.d.ts +7 -0
- package/dist/editor/field-types/NameValueListEditor.js +99 -0
- package/dist/editor/field-types/NameValueListEditor.js.map +1 -0
- package/dist/editor/fieldTypes.d.ts +1 -1
- package/dist/editor/page-editor-chrome/FrameMenu.js +47 -10
- package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZone.d.ts +3 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZone.js +30 -4
- package/dist/editor/page-editor-chrome/PlaceholderDropZone.js.map +1 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZones.js +44 -5
- package/dist/editor/page-editor-chrome/PlaceholderDropZones.js.map +1 -1
- package/dist/editor/services/agentService.d.ts +22 -2
- package/dist/editor/services/agentService.js +26 -1
- package/dist/editor/services/agentService.js.map +1 -1
- package/dist/editor/services/aiService.d.ts +2 -1
- package/dist/editor/services/aiService.js.map +1 -1
- package/dist/editor/sidebar/GraphQL.js +47 -90
- package/dist/editor/sidebar/GraphQL.js.map +1 -1
- package/dist/editor/ui/DragPreview.d.ts +13 -0
- package/dist/editor/ui/DragPreview.js +35 -0
- package/dist/editor/ui/DragPreview.js.map +1 -0
- package/dist/editor/ui/ItemNameDialogNew.js +2 -2
- package/dist/editor/ui/ItemNameDialogNew.js.map +1 -1
- package/dist/editor/ui/PerfectTree.js +3 -15
- package/dist/editor/ui/PerfectTree.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/styles.css +37 -9
- package/dist/tour/default-tour.js +34 -38
- package/dist/tour/default-tour.js.map +1 -1
- package/package.json +1 -1
- package/src/components/ui/context-menu.tsx +31 -19
- package/src/config/config.tsx +9 -1
- package/src/config/types.ts +1 -0
- package/src/editor/ContentTree.tsx +13 -18
- package/src/editor/ContextMenu.tsx +112 -19
- package/src/editor/MainLayout.tsx +1 -1
- package/src/editor/ai/AgentHistory.tsx +2 -2
- package/src/editor/ai/AgentTerminal.tsx +226 -15
- package/src/editor/ai/AiResponseMessage.tsx +1 -1
- package/src/editor/ai/types.ts +27 -0
- package/src/editor/client/EditorShell.tsx +31 -0
- package/src/editor/client/editContext.ts +12 -1
- package/src/editor/commands/agentCommands.tsx +49 -0
- package/src/editor/commands/itemCommands.tsx +26 -14
- package/src/editor/component-designer/aiContext.ts +1 -1
- package/src/editor/context-menu/InsertMenu.tsx +64 -39
- package/src/editor/field-types/NameValueListEditor.tsx +197 -0
- package/src/editor/fieldTypes.ts +1 -1
- package/src/editor/page-editor-chrome/FrameMenu.tsx +61 -13
- package/src/editor/page-editor-chrome/PlaceholderDropZone.tsx +82 -20
- package/src/editor/page-editor-chrome/PlaceholderDropZones.tsx +77 -24
- package/src/editor/services/agentService.ts +53 -2
- package/src/editor/services/aiService.ts +3 -1
- package/src/editor/sidebar/GraphQL.tsx +50 -99
- package/src/editor/ui/DragPreview.tsx +44 -0
- package/src/editor/ui/ItemNameDialogNew.tsx +7 -3
- package/src/editor/ui/PerfectTree.tsx +2 -17
- package/src/revision.ts +2 -2
- package/src/tour/default-tour.tsx +34 -46
- package/dist/editor/ai/AiTerminal.d.ts +0 -47
- package/dist/editor/ai/AiTerminal.js +0 -300
- package/dist/editor/ai/AiTerminal.js.map +0 -1
- package/src/editor/ai/AiTerminal.tsx +0 -570
- package/src/editor/component-designer/ComponentDesignerAiTerminal.tsx_ +0 -11
|
@@ -8,8 +8,7 @@ import { useEffect, useState } from "react";
|
|
|
8
8
|
import { useEditContext } from "../client/editContext";
|
|
9
9
|
import { ObjectInspector } from "react-inspector";
|
|
10
10
|
import { SimpleTabs } from "../ui/SimpleTabs";
|
|
11
|
-
import {
|
|
12
|
-
import { createEditorAiContext } from "../ai/editorAiContext";
|
|
11
|
+
import { createAgentCommand } from "../commands/agentCommands";
|
|
13
12
|
import { RefreshCw } from "lucide-react";
|
|
14
13
|
|
|
15
14
|
export function GraphQL() {
|
|
@@ -42,6 +41,29 @@ export function GraphQL() {
|
|
|
42
41
|
fetchSchema();
|
|
43
42
|
}
|
|
44
43
|
}, [activeTab]);
|
|
44
|
+
// Register a context factory for GraphQL so agents can pull structured context without tool reads
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (!editContext || !item) return;
|
|
47
|
+
const factoryName = "graphql:context:v1";
|
|
48
|
+
const factory = async () => ({
|
|
49
|
+
schema: schemaResult?.data || "",
|
|
50
|
+
currentQuery: query,
|
|
51
|
+
itemContext: {
|
|
52
|
+
id: item.id,
|
|
53
|
+
language: item.language,
|
|
54
|
+
version: item.version,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
editContext.registerContextFactory?.(factoryName, factory);
|
|
58
|
+
return () => editContext.unregisterContextFactory?.(factoryName);
|
|
59
|
+
}, [
|
|
60
|
+
editContext,
|
|
61
|
+
item?.id,
|
|
62
|
+
item?.language,
|
|
63
|
+
item?.version,
|
|
64
|
+
query,
|
|
65
|
+
schemaResult?.data,
|
|
66
|
+
]);
|
|
45
67
|
|
|
46
68
|
// if (item) {
|
|
47
69
|
// const selectedComponents = editContext!.selection
|
|
@@ -190,48 +212,10 @@ export function GraphQL() {
|
|
|
190
212
|
return match ? match[1]?.trim() || null : null;
|
|
191
213
|
};
|
|
192
214
|
|
|
193
|
-
//
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
return {
|
|
199
|
-
...baseContext,
|
|
200
|
-
endpoint: "/alpaca/editor/graphql/prompt",
|
|
201
|
-
promptData: {
|
|
202
|
-
...baseContext.promptData,
|
|
203
|
-
graphqlSchema: schemaResult?.data || null,
|
|
204
|
-
currentQuery: query,
|
|
205
|
-
itemContext: {
|
|
206
|
-
id: item.id,
|
|
207
|
-
language: item.language,
|
|
208
|
-
version: item.version,
|
|
209
|
-
},
|
|
210
|
-
},
|
|
211
|
-
callback: (response: any) => {
|
|
212
|
-
// Check if the AI response contains a GraphQL query
|
|
213
|
-
if (
|
|
214
|
-
response?.messages &&
|
|
215
|
-
Array.isArray(response.messages) &&
|
|
216
|
-
response.messages.length > 0
|
|
217
|
-
) {
|
|
218
|
-
const lastMessage = response.messages[response.messages.length - 1];
|
|
219
|
-
if (
|
|
220
|
-
lastMessage &&
|
|
221
|
-
lastMessage.role === "assistant" &&
|
|
222
|
-
lastMessage.content
|
|
223
|
-
) {
|
|
224
|
-
const extractedQuery = extractGraphQLFromResponse(
|
|
225
|
-
lastMessage.content,
|
|
226
|
-
);
|
|
227
|
-
if (extractedQuery) {
|
|
228
|
-
setAiGeneratedQuery(extractedQuery);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
},
|
|
233
|
-
};
|
|
234
|
-
};
|
|
215
|
+
// removed old AiTerminal context
|
|
216
|
+
|
|
217
|
+
// Register a context factory for GraphQL so agents can pull structured context without tool reads
|
|
218
|
+
// (moved useEffect for context factory above to ensure hooks order remains stable)
|
|
235
219
|
|
|
236
220
|
return (
|
|
237
221
|
<Splitter layout="vertical" style={{ height: "100%" }}>
|
|
@@ -306,61 +290,6 @@ export function GraphQL() {
|
|
|
306
290
|
<SimpleTabs
|
|
307
291
|
className="border-gray-3 border-b px-2 pt-2"
|
|
308
292
|
tabs={[
|
|
309
|
-
{
|
|
310
|
-
id: "ai",
|
|
311
|
-
label: "AI Assistant",
|
|
312
|
-
icon: "pi pi-star",
|
|
313
|
-
content: (
|
|
314
|
-
<div className="relative h-full overflow-hidden">
|
|
315
|
-
<AiTerminal
|
|
316
|
-
createAiContext={createGraphQLAiContext}
|
|
317
|
-
defaultProfile="GraphQL Assistant"
|
|
318
|
-
options={{
|
|
319
|
-
hiddenSystemPrompt: `You are an expert GraphQL assistant. Help the user create, modify, and understand GraphQL queries.
|
|
320
|
-
|
|
321
|
-
Current Context:
|
|
322
|
-
- Item ID: ${item?.id}
|
|
323
|
-
- Language: ${item?.language}
|
|
324
|
-
- Version: ${item?.version}
|
|
325
|
-
- Current Query: ${query || "No query set"}
|
|
326
|
-
- Schema Available: ${schemaResult?.data ? "Yes" : "No"}
|
|
327
|
-
|
|
328
|
-
${
|
|
329
|
-
schemaResult?.data
|
|
330
|
-
? `GraphQL Schema:
|
|
331
|
-
\`\`\`
|
|
332
|
-
${schemaResult.data}
|
|
333
|
-
\`\`\`
|
|
334
|
-
|
|
335
|
-
`
|
|
336
|
-
: ""
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
Instructions:
|
|
340
|
-
1. When helping with GraphQL queries, always consider the available schema
|
|
341
|
-
2. Provide working GraphQL query examples
|
|
342
|
-
3. Explain the query structure and what each part does
|
|
343
|
-
4. If the user wants to update the query, provide the complete new query
|
|
344
|
-
5. Always validate queries against the schema when possible
|
|
345
|
-
6. Help with both queries and mutations
|
|
346
|
-
7. Suggest optimizations and best practices
|
|
347
|
-
|
|
348
|
-
When updating queries, respond with the updated query in this format:
|
|
349
|
-
\`\`\`graphql
|
|
350
|
-
[your updated query here]
|
|
351
|
-
\`\`\`
|
|
352
|
-
|
|
353
|
-
Available operations:
|
|
354
|
-
- You can help craft new queries
|
|
355
|
-
- You can modify existing queries
|
|
356
|
-
- You can explain GraphQL concepts
|
|
357
|
-
- You can suggest optimizations
|
|
358
|
-
- You can help with error troubleshooting`,
|
|
359
|
-
}}
|
|
360
|
-
/>
|
|
361
|
-
</div>
|
|
362
|
-
),
|
|
363
|
-
},
|
|
364
293
|
{
|
|
365
294
|
id: "schema",
|
|
366
295
|
label: "Schema",
|
|
@@ -388,6 +317,28 @@ Available operations:
|
|
|
388
317
|
activeTab={activeTab}
|
|
389
318
|
setActiveTab={setActiveTab}
|
|
390
319
|
/>
|
|
320
|
+
<div className="border-t border-gray-200 p-2">
|
|
321
|
+
<ActionButton
|
|
322
|
+
variant="outline"
|
|
323
|
+
className="text-xs"
|
|
324
|
+
onClick={() => {
|
|
325
|
+
editContext?.executeCommand?.({
|
|
326
|
+
command: createAgentCommand,
|
|
327
|
+
data: {
|
|
328
|
+
profileName: "GraphQL Assistant",
|
|
329
|
+
contextFactory: "graphql:context:v1",
|
|
330
|
+
initialPrompt:
|
|
331
|
+
"Help with the current GraphQL query and schema.",
|
|
332
|
+
additionalData: {
|
|
333
|
+
source: "GraphQLPanel",
|
|
334
|
+
},
|
|
335
|
+
},
|
|
336
|
+
});
|
|
337
|
+
}}
|
|
338
|
+
>
|
|
339
|
+
Start GraphQL Agent
|
|
340
|
+
</ActionButton>
|
|
341
|
+
</div>
|
|
391
342
|
</div>
|
|
392
343
|
</SplitterPanel>
|
|
393
344
|
</Splitter>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Lightweight React component for consistent multi-select drag previews.
|
|
5
|
+
* Use with renderToString or by creating a DOM node and setting innerHTML.
|
|
6
|
+
*/
|
|
7
|
+
export function DragMultiSelectPreview({ count }: { count: number }) {
|
|
8
|
+
return (
|
|
9
|
+
<div className="rounded-md border border-gray-300 bg-white px-4 py-2 pl-8 text-sm shadow-md">
|
|
10
|
+
<div className="flex items-center">
|
|
11
|
+
<span className="mr-1 font-bold">{count}</span>
|
|
12
|
+
<span>components</span>
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Imperative helper to attach a consistent multi-select drag image.
|
|
20
|
+
* Returns a cleanup function that removes the temporary element.
|
|
21
|
+
*/
|
|
22
|
+
export function setMultiDragImage(
|
|
23
|
+
event: React.DragEvent<any>,
|
|
24
|
+
count: number,
|
|
25
|
+
): () => void {
|
|
26
|
+
const temp = document.createElement("div");
|
|
27
|
+
temp.className =
|
|
28
|
+
"bg-white shadow-md rounded-md border border-gray-300 px-4 pl-8 py-2 text-sm absolute top-[-1000px] left-[-1000px]";
|
|
29
|
+
temp.innerHTML = `<div class="flex items-center"><span class="font-bold mr-1">${count}</span> components</div>`;
|
|
30
|
+
document.body.appendChild(temp);
|
|
31
|
+
try {
|
|
32
|
+
event.dataTransfer.setDragImage(temp, 15, 15);
|
|
33
|
+
event.dataTransfer.dropEffect = "move";
|
|
34
|
+
event.dataTransfer.effectAllowed = "move";
|
|
35
|
+
} catch {}
|
|
36
|
+
const cleanup = () => {
|
|
37
|
+
try {
|
|
38
|
+
document.body.removeChild(temp);
|
|
39
|
+
} catch {}
|
|
40
|
+
};
|
|
41
|
+
// Defer cleanup to next tick so the drag image is captured.
|
|
42
|
+
setTimeout(cleanup, 0);
|
|
43
|
+
return cleanup;
|
|
44
|
+
}
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
|
|
8
8
|
import { useEffect, useRef, useState } from "react";
|
|
9
9
|
import DialogButtons from "./DialogButtons";
|
|
10
|
-
import { Button } from "
|
|
10
|
+
import { Button } from "../../components/ui/button";
|
|
11
11
|
import { InputText } from "primereact/inputtext";
|
|
12
12
|
import { DialogProps } from "../client/editContext";
|
|
13
13
|
import { ItemDescriptor } from "../pageModel";
|
|
@@ -137,8 +137,12 @@ export function ItemNameDialog(
|
|
|
137
137
|
)}
|
|
138
138
|
</div>
|
|
139
139
|
<DialogButtons>
|
|
140
|
-
<Button onClick={handleOk}
|
|
141
|
-
|
|
140
|
+
<Button onClick={handleOk} disabled={!isValid}>
|
|
141
|
+
Ok
|
|
142
|
+
</Button>
|
|
143
|
+
<Button onClick={() => props.onClose?.(null)} variant="ghost">
|
|
144
|
+
Cancel
|
|
145
|
+
</Button>
|
|
142
146
|
</DialogButtons>
|
|
143
147
|
</DialogContent>
|
|
144
148
|
</Dialog>
|
|
@@ -9,6 +9,7 @@ import React, {
|
|
|
9
9
|
|
|
10
10
|
import { ProgressSpinner } from "primereact/progressspinner";
|
|
11
11
|
import { ChevronRight } from "lucide-react";
|
|
12
|
+
import { setMultiDragImage } from "../ui/DragPreview";
|
|
12
13
|
export interface TreeNode<T = any> {
|
|
13
14
|
key: string;
|
|
14
15
|
label: string;
|
|
@@ -406,23 +407,7 @@ const NodeContent = memo(
|
|
|
406
407
|
isSelected && selectedKeys && selectedKeys.length > 1;
|
|
407
408
|
|
|
408
409
|
// Set drag preview for multiple items if applicable
|
|
409
|
-
if (isMultiSelect)
|
|
410
|
-
// Create custom drag image showing count of selected items
|
|
411
|
-
const dragPreview = document.createElement("div");
|
|
412
|
-
dragPreview.className =
|
|
413
|
-
"bg-white shadow-md rounded-md border border-gray-300 px-2 py-1 text-sm max-w-24 absolute top-[-1000px] left-[-1000px]";
|
|
414
|
-
dragPreview.innerHTML = `<div class="flex items-center"><span class="font-bold mr-1">${selectedKeys.length}</span> items</div>`;
|
|
415
|
-
document.body.appendChild(dragPreview);
|
|
416
|
-
|
|
417
|
-
// Set custom drag image
|
|
418
|
-
event.dataTransfer.setDragImage(dragPreview, 15, 15);
|
|
419
|
-
event.dataTransfer.dropEffect = "move";
|
|
420
|
-
|
|
421
|
-
// Remove the element after drag starts
|
|
422
|
-
setTimeout(() => {
|
|
423
|
-
document.body.removeChild(dragPreview);
|
|
424
|
-
}, 0);
|
|
425
|
-
}
|
|
410
|
+
if (isMultiSelect) setMultiDragImage(event, selectedKeys.length);
|
|
426
411
|
if (onStartDrag) {
|
|
427
412
|
onStartDrag({ node, event, isMultiSelect: isMultiSelect ?? false });
|
|
428
413
|
}
|
package/src/revision.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const version = "1.0.
|
|
2
|
-
export const buildDate = "2025-09-23
|
|
1
|
+
export const version = "1.0.4104";
|
|
2
|
+
export const buildDate = "2025-09-23 14:05:05";
|
|
@@ -52,7 +52,8 @@ export function getDefaultTourSteps(
|
|
|
52
52
|
className: "button button-secondary mt-2",
|
|
53
53
|
},
|
|
54
54
|
],
|
|
55
|
-
},
|
|
55
|
+
},
|
|
56
|
+
"new-page": {
|
|
56
57
|
title: "Create a New Page",
|
|
57
58
|
description: (
|
|
58
59
|
<>
|
|
@@ -65,20 +66,18 @@ export function getDefaultTourSteps(
|
|
|
65
66
|
await waitForElement(".tour-pick-location");
|
|
66
67
|
},
|
|
67
68
|
nextStep: "pick-location",
|
|
68
|
-
},
|
|
69
|
+
},
|
|
70
|
+
"pick-location": {
|
|
69
71
|
title: "Choose Location",
|
|
70
|
-
description:
|
|
71
|
-
<>
|
|
72
|
-
Open up a folder for your page
|
|
73
|
-
</>
|
|
74
|
-
),
|
|
72
|
+
description: <>Open up a folder for your page</>,
|
|
75
73
|
focusElement: ".tour-pick-location",
|
|
76
74
|
bubblePosition: "right",
|
|
77
75
|
waitForUserInput: async () => {
|
|
78
76
|
await waitForElement(".bg-theme-secondary-light");
|
|
79
77
|
},
|
|
80
78
|
nextStep: "choose-template",
|
|
81
|
-
},
|
|
79
|
+
},
|
|
80
|
+
"choose-template": {
|
|
82
81
|
title: "Select Template",
|
|
83
82
|
description: "Select a template for your page",
|
|
84
83
|
focusElement: ".tour-choose-template",
|
|
@@ -96,7 +95,8 @@ export function getDefaultTourSteps(
|
|
|
96
95
|
},
|
|
97
96
|
bubblePosition: "left",
|
|
98
97
|
nextStep: "enter-name",
|
|
99
|
-
},
|
|
98
|
+
},
|
|
99
|
+
"enter-name": {
|
|
100
100
|
title: "Name Your Page",
|
|
101
101
|
description: "Enter a name for your page",
|
|
102
102
|
focusElement: "#new-page-name",
|
|
@@ -105,7 +105,8 @@ export function getDefaultTourSteps(
|
|
|
105
105
|
await waitForElement("#create-new-page-button:not([disabled])");
|
|
106
106
|
},
|
|
107
107
|
nextStep: "create-page",
|
|
108
|
-
},
|
|
108
|
+
},
|
|
109
|
+
"create-page": {
|
|
109
110
|
title: "Create Page",
|
|
110
111
|
description: "Click the Create button",
|
|
111
112
|
focusElement: "#create-new-page-button",
|
|
@@ -115,14 +116,16 @@ export function getDefaultTourSteps(
|
|
|
115
116
|
await waitForElement(".pi-cog");
|
|
116
117
|
},
|
|
117
118
|
nextStep: "loading",
|
|
118
|
-
},
|
|
119
|
+
},
|
|
120
|
+
loading: {
|
|
119
121
|
title: "Loading...",
|
|
120
122
|
description: "Waiting for your new page...",
|
|
121
123
|
waitForUserInput: async () => {
|
|
122
124
|
await waitForElementToDisappear(".pi-cog");
|
|
123
125
|
},
|
|
124
126
|
nextStep: "ready-to-add-component",
|
|
125
|
-
},
|
|
127
|
+
},
|
|
128
|
+
"ready-to-add-component": {
|
|
126
129
|
title: "Ready to Add Components",
|
|
127
130
|
description: "Wanna add a component to your beautiful empty page?",
|
|
128
131
|
buttons: [
|
|
@@ -141,7 +144,8 @@ export function getDefaultTourSteps(
|
|
|
141
144
|
},
|
|
142
145
|
},
|
|
143
146
|
],
|
|
144
|
-
},
|
|
147
|
+
},
|
|
148
|
+
"insert-component": {
|
|
145
149
|
title: "Insert Component",
|
|
146
150
|
description: "Excellent, click on the plus button to insert a component.",
|
|
147
151
|
focusElement: "#insert-component-button",
|
|
@@ -150,7 +154,8 @@ export function getDefaultTourSteps(
|
|
|
150
154
|
await waitForElement(".tour-component-palette");
|
|
151
155
|
},
|
|
152
156
|
nextStep: "drag-component",
|
|
153
|
-
},
|
|
157
|
+
},
|
|
158
|
+
"drag-component": {
|
|
154
159
|
title: "Drag & Drop Component",
|
|
155
160
|
description: `Drag and drop a ${config.firstComponentTemplateName} component to your page.`,
|
|
156
161
|
focusElement: `#insert-component-${config.firstComponentTemplateId}`,
|
|
@@ -159,7 +164,8 @@ export function getDefaultTourSteps(
|
|
|
159
164
|
await waitForElement(".tour-placeholder-dropzone");
|
|
160
165
|
},
|
|
161
166
|
nextStep: "drop-component-on-placeholder",
|
|
162
|
-
},
|
|
167
|
+
},
|
|
168
|
+
"drop-component-on-placeholder": {
|
|
163
169
|
title: "Drop Here!",
|
|
164
170
|
description: "Drop the component onto this placeholder!",
|
|
165
171
|
focusElement: ".tour-placeholder-dropzone",
|
|
@@ -174,7 +180,8 @@ export function getDefaultTourSteps(
|
|
|
174
180
|
return "drag-component";
|
|
175
181
|
},
|
|
176
182
|
nextStep: "enter-title",
|
|
177
|
-
},
|
|
183
|
+
},
|
|
184
|
+
"enter-title": {
|
|
178
185
|
title: "Fill in Content",
|
|
179
186
|
description: `Excellent! Now lets fill in the fields. First enter a ${config.firstComponentTextFieldName}`,
|
|
180
187
|
focusElement: `[data-field-id='${config.firstComponentTextFieldId}']`,
|
|
@@ -186,7 +193,8 @@ export function getDefaultTourSteps(
|
|
|
186
193
|
);
|
|
187
194
|
},
|
|
188
195
|
nextStep: "see-content-update",
|
|
189
|
-
},
|
|
196
|
+
},
|
|
197
|
+
"see-content-update": {
|
|
190
198
|
title: "Live Updates",
|
|
191
199
|
description:
|
|
192
200
|
"See how the content is automatically updating on your page?",
|
|
@@ -202,7 +210,8 @@ export function getDefaultTourSteps(
|
|
|
202
210
|
);
|
|
203
211
|
},
|
|
204
212
|
nextStep: "edit-content-inline",
|
|
205
|
-
},
|
|
213
|
+
},
|
|
214
|
+
"edit-content-inline": {
|
|
206
215
|
title: "Inline Editing",
|
|
207
216
|
description:
|
|
208
217
|
"You can also directly edit the content on the page. Click on the [Introduction] placeholder here and start typing!",
|
|
@@ -217,7 +226,8 @@ export function getDefaultTourSteps(
|
|
|
217
226
|
);
|
|
218
227
|
},
|
|
219
228
|
nextStep: "ai-intro",
|
|
220
|
-
},
|
|
229
|
+
},
|
|
230
|
+
"ai-intro": {
|
|
221
231
|
title: "AI-Powered Editing",
|
|
222
232
|
description:
|
|
223
233
|
"But hey, this is an AI editor, so why not let the AI do some of the work for you?",
|
|
@@ -231,45 +241,23 @@ export function getDefaultTourSteps(
|
|
|
231
241
|
onClick: () => nextStep("ai-sidebar"),
|
|
232
242
|
},
|
|
233
243
|
],
|
|
234
|
-
},
|
|
244
|
+
},
|
|
245
|
+
"ai-sidebar": {
|
|
235
246
|
title: "Open AI Chat",
|
|
236
247
|
description: "Click on the AI sidebar to open the AI chat.",
|
|
237
248
|
focusElement: `[data-sidebarview-name='ai']`,
|
|
238
249
|
bubblePosition: "right",
|
|
239
250
|
nextStep: "ai-terminal",
|
|
240
251
|
waitForElement: "[data-sidebarview-name='ai'].active",
|
|
241
|
-
},
|
|
252
|
+
},
|
|
253
|
+
"ai-terminal": {
|
|
242
254
|
title: "AI Assistant",
|
|
243
255
|
description:
|
|
244
|
-
"
|
|
245
|
-
focusElement: `.tour-ai-terminal textarea`,
|
|
256
|
+
"Open the Agents panel (top-right) and start an agent to add components.",
|
|
246
257
|
waitForUserInput: async () => {
|
|
247
258
|
await delay(1000);
|
|
248
|
-
const aiTerminal = document.querySelector(".tour-ai-terminal textarea");
|
|
249
|
-
if (aiTerminal) {
|
|
250
|
-
(aiTerminal as HTMLTextAreaElement).focus();
|
|
251
|
-
await simulateTyping(
|
|
252
|
-
aiTerminal as HTMLTextAreaElement,
|
|
253
|
-
`Please add three components of type ${config.firstComponentTemplateName} with some funny dummy content to the page.`,
|
|
254
|
-
);
|
|
255
|
-
}
|
|
256
259
|
},
|
|
257
260
|
bubblePosition: "top-right",
|
|
258
|
-
nextStep: "ai-submit",
|
|
259
|
-
}, "ai-submit": {
|
|
260
|
-
title: "Send AI Request",
|
|
261
|
-
description: "Click on the Send button to submit the prompt to the AI.",
|
|
262
|
-
focusElement: ".tour-ai-terminal .tour-send-button",
|
|
263
|
-
bubblePosition: "top-right",
|
|
264
|
-
nextStep: "ai-watch-components-added",
|
|
265
|
-
waitForElement: ".tour-ai-terminal .prompt",
|
|
266
|
-
}, "ai-watch-components-added": {
|
|
267
|
-
title: "AI Magic in Action",
|
|
268
|
-
description:
|
|
269
|
-
"Watch how the AI adds the components to the page. This can take a few seconds.",
|
|
270
|
-
focusElement: ".tour-ai-terminal",
|
|
271
|
-
pointToElement: ".tour-ai-terminal .prompt",
|
|
272
|
-
waitForElement: ".tour-ai-response-message-changes",
|
|
273
261
|
nextStep: "congratulations",
|
|
274
262
|
},
|
|
275
263
|
congratulations: {
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { EditContextType } from "../client/editContext";
|
|
2
|
-
import { EditOperation } from "../../types";
|
|
3
|
-
type Response = {
|
|
4
|
-
messages: Message[];
|
|
5
|
-
editOperations: EditOperation[];
|
|
6
|
-
numInputTokens: number;
|
|
7
|
-
numOutputTokens: number;
|
|
8
|
-
numCachedTokens: number;
|
|
9
|
-
state: string;
|
|
10
|
-
};
|
|
11
|
-
export type ToolCall = {
|
|
12
|
-
id: string;
|
|
13
|
-
displayName: string;
|
|
14
|
-
function: {
|
|
15
|
-
name: string;
|
|
16
|
-
arguments: string;
|
|
17
|
-
};
|
|
18
|
-
};
|
|
19
|
-
export type Message = {
|
|
20
|
-
id: string;
|
|
21
|
-
content: string;
|
|
22
|
-
formattedContent?: string;
|
|
23
|
-
name: string;
|
|
24
|
-
role: string;
|
|
25
|
-
tool_calls?: ToolCall[];
|
|
26
|
-
tool_call_id?: string;
|
|
27
|
-
createdDate?: string;
|
|
28
|
-
};
|
|
29
|
-
export type AiContext = {
|
|
30
|
-
promptData: any;
|
|
31
|
-
endpoint?: string;
|
|
32
|
-
callback?: (response: Response) => void;
|
|
33
|
-
};
|
|
34
|
-
export type AiTerminalOptions = {
|
|
35
|
-
initialPrompt?: string;
|
|
36
|
-
hiddenSystemPrompt?: string;
|
|
37
|
-
initialMessages?: Message[];
|
|
38
|
-
};
|
|
39
|
-
export declare function AiTerminal({ closeButton, createAiContext, defaultProfile, options, }: {
|
|
40
|
-
closeButton?: React.ReactNode;
|
|
41
|
-
createAiContext: ({ editContext, }: {
|
|
42
|
-
editContext: EditContextType;
|
|
43
|
-
}) => AiContext;
|
|
44
|
-
defaultProfile?: string;
|
|
45
|
-
options?: AiTerminalOptions;
|
|
46
|
-
}): import("react/jsx-runtime").JSX.Element | null;
|
|
47
|
-
export {};
|