@alpaca-editor/core 1.0.4112 → 1.0.4118
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/FilterInput.js +3 -7
- package/dist/components/FilterInput.js.map +1 -1
- package/dist/components/ui/context-menu.js +3 -0
- package/dist/components/ui/context-menu.js.map +1 -1
- package/dist/components/ui/input.js +1 -1
- package/dist/components/ui/input.js.map +1 -1
- package/dist/config/config.js +3 -3
- package/dist/config/config.js.map +1 -1
- package/dist/editor/AspectRatioSelector.js +3 -3
- package/dist/editor/AspectRatioSelector.js.map +1 -1
- package/dist/editor/EditorWarning.js +2 -2
- package/dist/editor/EditorWarning.js.map +1 -1
- package/dist/editor/FieldEditorPopup.js +7 -6
- package/dist/editor/FieldEditorPopup.js.map +1 -1
- package/dist/editor/FieldHistory.js +2 -1
- package/dist/editor/FieldHistory.js.map +1 -1
- package/dist/editor/LinkEditorDialog.d.ts +3 -1
- package/dist/editor/LinkEditorDialog.js +7 -3
- package/dist/editor/LinkEditorDialog.js.map +1 -1
- package/dist/editor/MainLayout.js +3 -3
- package/dist/editor/MainLayout.js.map +1 -1
- package/dist/editor/PictureCropper.js +3 -3
- package/dist/editor/PictureCropper.js.map +1 -1
- package/dist/editor/PictureEditorDialog.js +55 -50
- package/dist/editor/PictureEditorDialog.js.map +1 -1
- package/dist/editor/Terminal.js +4 -4
- package/dist/editor/Terminal.js.map +1 -1
- package/dist/editor/ai/AgentTerminal.js +137 -6
- package/dist/editor/ai/AgentTerminal.js.map +1 -1
- package/dist/editor/ai/Agents.js +2 -2
- package/dist/editor/ai/Agents.js.map +1 -1
- package/dist/editor/ai/ContextInfoBar.js +1 -1
- package/dist/editor/ai/ContextInfoBar.js.map +1 -1
- package/dist/editor/client/EditorShell.js +2 -0
- package/dist/editor/client/EditorShell.js.map +1 -1
- package/dist/editor/client/GenericDialog.js +3 -3
- package/dist/editor/client/GenericDialog.js.map +1 -1
- package/dist/editor/client/hooks/useGlobalEditorKeyDown.d.ts +1 -0
- package/dist/editor/client/hooks/useGlobalEditorKeyDown.js +12 -0
- package/dist/editor/client/hooks/useGlobalEditorKeyDown.js.map +1 -0
- package/dist/editor/client/ui/EditorChrome.js +8 -2
- package/dist/editor/client/ui/EditorChrome.js.map +1 -1
- package/dist/editor/commands/localizeItem/LocalizeItemDialog.js +9 -7
- package/dist/editor/commands/localizeItem/LocalizeItemDialog.js.map +1 -1
- package/dist/editor/context-menu/CopyMoveMenu.js +3 -3
- package/dist/editor/context-menu/CopyMoveMenu.js.map +1 -1
- package/dist/editor/control-center/IndexOverview.js +39 -17
- package/dist/editor/control-center/IndexOverview.js.map +1 -1
- package/dist/editor/field-types/CheckboxEditor.js +2 -2
- package/dist/editor/field-types/CheckboxEditor.js.map +1 -1
- package/dist/editor/field-types/DateFieldEditor.js +2 -2
- package/dist/editor/field-types/DateFieldEditor.js.map +1 -1
- package/dist/editor/field-types/DateTimeFieldEditor.js.map +1 -1
- package/dist/editor/field-types/ImageFieldEditor.js +2 -2
- package/dist/editor/field-types/ImageFieldEditor.js.map +1 -1
- package/dist/editor/field-types/InternalLinkFieldEditor.js +2 -2
- package/dist/editor/field-types/InternalLinkFieldEditor.js.map +1 -1
- package/dist/editor/field-types/LinkFieldEditor.js +8 -3
- package/dist/editor/field-types/LinkFieldEditor.js.map +1 -1
- package/dist/editor/field-types/MultiLineText.js +2 -2
- package/dist/editor/field-types/MultiLineText.js.map +1 -1
- package/dist/editor/field-types/PictureFieldEditor.js +3 -2
- package/dist/editor/field-types/PictureFieldEditor.js.map +1 -1
- package/dist/editor/field-types/RawEditor.js +2 -2
- package/dist/editor/field-types/RawEditor.js.map +1 -1
- package/dist/editor/field-types/SingleLineText.js +2 -2
- package/dist/editor/field-types/SingleLineText.js.map +1 -1
- package/dist/editor/field-types/richtext/components/ReactSlate.js +2 -2
- package/dist/editor/field-types/richtext/components/ReactSlate.js.map +1 -1
- package/dist/editor/field-types/richtext/components/SimpleRichTextEditor.js +2 -2
- package/dist/editor/field-types/richtext/components/SimpleRichTextEditor.js.map +1 -1
- package/dist/editor/fieldTypes.d.ts +1 -0
- package/dist/editor/media-selector/AiImageSearch.js +5 -4
- package/dist/editor/media-selector/AiImageSearch.js.map +1 -1
- package/dist/editor/media-selector/MediaFolderBrowser.js +8 -8
- package/dist/editor/media-selector/MediaFolderBrowser.js.map +1 -1
- package/dist/editor/media-selector/Thumbnails.js +2 -2
- package/dist/editor/media-selector/Thumbnails.js.map +1 -1
- package/dist/editor/media-selector/TreeSelector.js +2 -2
- package/dist/editor/media-selector/TreeSelector.js.map +1 -1
- package/dist/editor/media-selector/UploadZone.js +2 -2
- package/dist/editor/media-selector/UploadZone.js.map +1 -1
- package/dist/editor/menubar/NavButtons.js +3 -5
- package/dist/editor/menubar/NavButtons.js.map +1 -1
- package/dist/editor/menubar/Separator.js +2 -2
- package/dist/editor/menubar/Separator.js.map +1 -1
- package/dist/editor/menubar/SiteInfo.js +9 -9
- package/dist/editor/menubar/SiteInfo.js.map +1 -1
- package/dist/editor/page-editor-chrome/CommentHighlighting.js +2 -2
- package/dist/editor/page-editor-chrome/CommentHighlighting.js.map +1 -1
- package/dist/editor/page-editor-chrome/FieldActionIndicator.js +2 -2
- package/dist/editor/page-editor-chrome/FieldActionIndicator.js.map +1 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZone.js +6 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZone.js.map +1 -1
- package/dist/editor/page-editor-chrome/SuggestionHighlighting.js +2 -2
- package/dist/editor/page-editor-chrome/SuggestionHighlighting.js.map +1 -1
- package/dist/editor/page-viewer/DeviceToolbar.js +3 -3
- package/dist/editor/page-viewer/DeviceToolbar.js.map +1 -1
- package/dist/editor/reviews/CommentView.js +5 -3
- package/dist/editor/reviews/CommentView.js.map +1 -1
- package/dist/editor/reviews/Reviews.js +55 -54
- package/dist/editor/reviews/Reviews.js.map +1 -1
- package/dist/editor/services/agentService.d.ts +3 -3
- package/dist/editor/services/agentService.js.map +1 -1
- package/dist/editor/services/aiService.js +5 -5
- package/dist/editor/services/aiService.js.map +1 -1
- package/dist/editor/sidebar/ComponentPalette.js +3 -3
- package/dist/editor/sidebar/ComponentPalette.js.map +1 -1
- package/dist/editor/sidebar/ComponentTree.js +6 -1
- package/dist/editor/sidebar/ComponentTree.js.map +1 -1
- package/dist/editor/sidebar/DictionaryEditor.js +9 -9
- package/dist/editor/sidebar/DictionaryEditor.js.map +1 -1
- package/dist/editor/sidebar/EditHistory.js +4 -3
- package/dist/editor/sidebar/EditHistory.js.map +1 -1
- package/dist/editor/sidebar/SEOInfo.js +3 -2
- package/dist/editor/sidebar/SEOInfo.js.map +1 -1
- package/dist/editor/sidebar/SidebarView.js +13 -8
- package/dist/editor/sidebar/SidebarView.js.map +1 -1
- package/dist/editor/sidebar/Translations.js +5 -2
- package/dist/editor/sidebar/Translations.js.map +1 -1
- package/dist/editor/sidebar/Validation.js +2 -2
- package/dist/editor/sidebar/Validation.js.map +1 -1
- package/dist/editor/sidebar/ViewSelector.js +22 -5
- package/dist/editor/sidebar/ViewSelector.js.map +1 -1
- package/dist/editor/sidebar/Workbox.js +14 -13
- package/dist/editor/sidebar/Workbox.js.map +1 -1
- package/dist/editor/ui/ItemNameDialogNew.js +2 -2
- package/dist/editor/ui/ItemNameDialogNew.js.map +1 -1
- package/dist/editor/ui/PerfectTree.js +2 -2
- package/dist/editor/ui/PerfectTree.js.map +1 -1
- package/dist/editor/ui/Section.js +3 -3
- package/dist/editor/ui/Section.js.map +1 -1
- package/dist/editor/ui/SimpleTable.js +3 -3
- package/dist/editor/ui/SimpleTable.js.map +1 -1
- package/dist/editor/utils/keyboardNavigation.js +1 -0
- package/dist/editor/utils/keyboardNavigation.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 +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/page-wizard/WizardSteps.js +2 -3
- package/dist/page-wizard/WizardSteps.js.map +1 -1
- package/dist/page-wizard/steps/CollectStep.js +2 -2
- package/dist/page-wizard/steps/CollectStep.js.map +1 -1
- package/dist/page-wizard/steps/ContentStep.js +3 -4
- package/dist/page-wizard/steps/ContentStep.js.map +1 -1
- package/dist/page-wizard/steps/Generate.js +2 -2
- package/dist/page-wizard/steps/Generate.js.map +1 -1
- package/dist/page-wizard/steps/ImagesStep.js +17 -15
- package/dist/page-wizard/steps/ImagesStep.js.map +1 -1
- package/dist/page-wizard/steps/MetaDataStep.js +2 -2
- package/dist/page-wizard/steps/MetaDataStep.js.map +1 -1
- package/dist/page-wizard/steps/SelectStep.js +5 -5
- package/dist/page-wizard/steps/SelectStep.js.map +1 -1
- package/dist/page-wizard/steps/StructureStep.js +3 -3
- package/dist/page-wizard/steps/StructureStep.js.map +1 -1
- package/dist/page-wizard/steps/TranslateStep.js +2 -2
- 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 +2 -2
- package/dist/splash-screen/NewPage.js.map +1 -1
- package/dist/splash-screen/SectionHeadline.js +2 -2
- package/dist/splash-screen/SectionHeadline.js.map +1 -1
- package/dist/styles.css +9 -26
- package/package.json +1 -1
- package/src/components/FilterInput.tsx +13 -16
- package/src/components/ui/context-menu.tsx +3 -0
- package/src/components/ui/input.tsx +1 -1
- package/src/config/config.tsx +3 -3
- package/src/editor/AspectRatioSelector.tsx +3 -3
- package/src/editor/EditorWarning.tsx +6 -6
- package/src/editor/FieldEditorPopup.tsx +36 -26
- package/src/editor/FieldHistory.tsx +2 -1
- package/src/editor/LinkEditorDialog.tsx +20 -0
- package/src/editor/MainLayout.tsx +3 -3
- package/src/editor/PictureCropper.tsx +3 -3
- package/src/editor/PictureEditorDialog.tsx +167 -145
- package/src/editor/Terminal.tsx +5 -6
- package/src/editor/ai/AgentTerminal.tsx +187 -23
- package/src/editor/ai/Agents.tsx +2 -2
- package/src/editor/ai/ContextInfoBar.tsx +8 -6
- package/src/editor/client/EditorShell.tsx +3 -0
- package/src/editor/client/GenericDialog.tsx +13 -9
- package/src/editor/client/hooks/useGlobalEditorKeyDown.ts +11 -0
- package/src/editor/client/ui/EditorChrome.tsx +8 -4
- package/src/editor/commands/localizeItem/LocalizeItemDialog.tsx +30 -11
- package/src/editor/context-menu/CopyMoveMenu.tsx +5 -3
- package/src/editor/control-center/IndexOverview.tsx +63 -34
- package/src/editor/field-types/CheckboxEditor.tsx +2 -2
- package/src/editor/field-types/DateFieldEditor.tsx +2 -2
- package/src/editor/field-types/DateTimeFieldEditor.tsx +0 -1
- package/src/editor/field-types/ImageFieldEditor.tsx +3 -4
- package/src/editor/field-types/InternalLinkFieldEditor.tsx +2 -2
- package/src/editor/field-types/LinkFieldEditor.tsx +8 -2
- package/src/editor/field-types/MultiLineText.tsx +4 -5
- package/src/editor/field-types/PictureFieldEditor.tsx +5 -5
- package/src/editor/field-types/RawEditor.tsx +4 -5
- package/src/editor/field-types/SingleLineText.tsx +4 -6
- package/src/editor/field-types/richtext/components/ReactSlate.tsx +2 -2
- package/src/editor/field-types/richtext/components/SimpleRichTextEditor.tsx +2 -2
- package/src/editor/fieldTypes.ts +1 -0
- package/src/editor/media-selector/AiImageSearch.tsx +11 -14
- package/src/editor/media-selector/MediaFolderBrowser.tsx +42 -35
- package/src/editor/media-selector/Thumbnails.tsx +3 -3
- package/src/editor/media-selector/TreeSelector.tsx +2 -2
- package/src/editor/media-selector/UploadZone.tsx +2 -2
- package/src/editor/menubar/NavButtons.tsx +12 -14
- package/src/editor/menubar/Separator.tsx +2 -2
- package/src/editor/menubar/SiteInfo.tsx +29 -23
- package/src/editor/page-editor-chrome/CommentHighlighting.tsx +2 -2
- package/src/editor/page-editor-chrome/FieldActionIndicator.tsx +2 -2
- package/src/editor/page-editor-chrome/PlaceholderDropZone.tsx +6 -1
- package/src/editor/page-editor-chrome/SuggestionHighlighting.tsx +2 -2
- package/src/editor/page-viewer/DeviceToolbar.tsx +4 -3
- package/src/editor/reviews/CommentView.tsx +34 -10
- package/src/editor/reviews/Reviews.tsx +116 -106
- package/src/editor/services/agentService.ts +3 -3
- package/src/editor/services/aiService.ts +5 -5
- package/src/editor/sidebar/ComponentPalette.tsx +3 -3
- package/src/editor/sidebar/ComponentTree.tsx +10 -1
- package/src/editor/sidebar/DictionaryEditor.tsx +12 -13
- package/src/editor/sidebar/EditHistory.tsx +4 -3
- package/src/editor/sidebar/SEOInfo.tsx +9 -7
- package/src/editor/sidebar/SidebarView.tsx +16 -9
- package/src/editor/sidebar/Translations.tsx +9 -5
- package/src/editor/sidebar/Validation.tsx +2 -2
- package/src/editor/sidebar/ViewSelector.tsx +32 -6
- package/src/editor/sidebar/Workbox.tsx +81 -63
- package/src/editor/ui/ItemNameDialogNew.tsx +2 -2
- package/src/editor/ui/PerfectTree.tsx +2 -5
- package/src/editor/ui/Section.tsx +4 -4
- package/src/editor/ui/SimpleTable.tsx +3 -3
- package/src/editor/utils/keyboardNavigation.ts +1 -0
- package/src/editor/views/ItemEditor.tsx +1 -1
- package/src/index.ts +6 -0
- package/src/page-wizard/WizardSteps.tsx +2 -3
- package/src/page-wizard/steps/CollectStep.tsx +3 -3
- package/src/page-wizard/steps/ContentStep.tsx +4 -5
- package/src/page-wizard/steps/Generate.tsx +2 -2
- package/src/page-wizard/steps/ImagesStep.tsx +43 -24
- package/src/page-wizard/steps/MetaDataStep.tsx +5 -5
- package/src/page-wizard/steps/SelectStep.tsx +8 -6
- package/src/page-wizard/steps/StructureStep.tsx +9 -8
- package/src/page-wizard/steps/TranslateStep.tsx +5 -3
- package/src/revision.ts +2 -2
- package/src/splash-screen/NewPage.tsx +2 -2
- package/src/splash-screen/SectionHeadline.tsx +4 -4
- package/dist/editor/component-designer/ComponentDesigner.d.ts +0 -1
- package/dist/editor/component-designer/ComponentDesigner.js +0 -51
- package/dist/editor/component-designer/ComponentDesigner.js.map +0 -1
- package/dist/editor/component-designer/ComponentDesignerMenu.d.ts +0 -1
- package/dist/editor/component-designer/ComponentDesignerMenu.js +0 -65
- package/dist/editor/component-designer/ComponentDesignerMenu.js.map +0 -1
- package/dist/editor/component-designer/ComponentEditor.d.ts +0 -4
- package/dist/editor/component-designer/ComponentEditor.js +0 -55
- package/dist/editor/component-designer/ComponentEditor.js.map +0 -1
- package/dist/editor/component-designer/ComponentRenderingCodeEditor.d.ts +0 -5
- package/dist/editor/component-designer/ComponentRenderingCodeEditor.js +0 -11
- package/dist/editor/component-designer/ComponentRenderingCodeEditor.js.map +0 -1
- package/dist/editor/component-designer/ComponentRenderingEditor.d.ts +0 -1
- package/dist/editor/component-designer/ComponentRenderingEditor.js +0 -69
- package/dist/editor/component-designer/ComponentRenderingEditor.js.map +0 -1
- package/dist/editor/component-designer/ComponentsDropdown.d.ts +0 -4
- package/dist/editor/component-designer/ComponentsDropdown.js +0 -20
- package/dist/editor/component-designer/ComponentsDropdown.js.map +0 -1
- package/dist/editor/component-designer/PlaceholdersEditor.d.ts +0 -4
- package/dist/editor/component-designer/PlaceholdersEditor.js +0 -63
- package/dist/editor/component-designer/PlaceholdersEditor.js.map +0 -1
- package/dist/editor/component-designer/RenderingsDropdown.d.ts +0 -1
- package/dist/editor/component-designer/RenderingsDropdown.js +0 -23
- package/dist/editor/component-designer/RenderingsDropdown.js.map +0 -1
- package/dist/editor/component-designer/TemplateEditor.d.ts +0 -1
- package/dist/editor/component-designer/TemplateEditor.js +0 -142
- package/dist/editor/component-designer/TemplateEditor.js.map +0 -1
- package/dist/editor/component-designer/aiContext.d.ts +0 -5
- package/dist/editor/component-designer/aiContext.js +0 -14
- package/dist/editor/component-designer/aiContext.js.map +0 -1
- package/src/editor/component-designer/ComponentDesigner.tsx +0 -66
- package/src/editor/component-designer/ComponentDesignerMenu.tsx +0 -91
- package/src/editor/component-designer/ComponentEditor.tsx +0 -95
- package/src/editor/component-designer/ComponentRenderingCodeEditor.tsx +0 -31
- package/src/editor/component-designer/ComponentRenderingEditor.tsx +0 -104
- package/src/editor/component-designer/ComponentsDropdown.tsx +0 -39
- package/src/editor/component-designer/PlaceholdersEditor.tsx +0 -179
- package/src/editor/component-designer/RenderingsDropdown.tsx +0 -36
- package/src/editor/component-designer/TemplateEditor.tsx +0 -236
- package/src/editor/component-designer/aiContext.ts +0 -21
|
@@ -5,7 +5,16 @@ import React, {
|
|
|
5
5
|
useCallback,
|
|
6
6
|
useLayoutEffect,
|
|
7
7
|
} from "react";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
Send,
|
|
10
|
+
AlertCircle,
|
|
11
|
+
Loader2,
|
|
12
|
+
User,
|
|
13
|
+
Wand2,
|
|
14
|
+
Square,
|
|
15
|
+
Mic,
|
|
16
|
+
MicOff,
|
|
17
|
+
} from "lucide-react";
|
|
9
18
|
import { DancingDots } from "./DancingDots";
|
|
10
19
|
import {
|
|
11
20
|
AgentChatMessage,
|
|
@@ -197,6 +206,12 @@ export function AgentTerminal({
|
|
|
197
206
|
const [agentMetadata, setAgentMetadata] = useState<AgentMetadata | null>(
|
|
198
207
|
null,
|
|
199
208
|
);
|
|
209
|
+
// Voice input state
|
|
210
|
+
const [isVoiceSupported, setIsVoiceSupported] = useState(false);
|
|
211
|
+
const [isListening, setIsListening] = useState(false);
|
|
212
|
+
const recognitionRef = useRef<any>(null);
|
|
213
|
+
const prevPlaceholderRef = useRef<string | null>(null);
|
|
214
|
+
const [voiceError, setVoiceError] = useState<string | null>(null);
|
|
200
215
|
const [isWaitingForResponse, setIsWaitingForResponse] = useState(false);
|
|
201
216
|
const isWaitingRef = useRef<boolean>(false);
|
|
202
217
|
useEffect(() => {
|
|
@@ -256,7 +271,8 @@ export function AgentTerminal({
|
|
|
256
271
|
const [selectedModelId, setSelectedModelId] = useState<string | undefined>(
|
|
257
272
|
undefined,
|
|
258
273
|
);
|
|
259
|
-
|
|
274
|
+
type AgentMode = "agent" | "ask" | "restricted";
|
|
275
|
+
const [mode, setMode] = useState<AgentMode>("restricted");
|
|
260
276
|
|
|
261
277
|
// Read deterministic flags from query string once
|
|
262
278
|
const deterministicFlags = React.useMemo(() => {
|
|
@@ -337,6 +353,120 @@ export function AgentTerminal({
|
|
|
337
353
|
container.scrollTop = container.scrollHeight;
|
|
338
354
|
}, []);
|
|
339
355
|
|
|
356
|
+
// Detect speech recognition support (client-only)
|
|
357
|
+
useEffect(() => {
|
|
358
|
+
try {
|
|
359
|
+
if (typeof window === "undefined") return;
|
|
360
|
+
const SR =
|
|
361
|
+
(window as any).SpeechRecognition ||
|
|
362
|
+
(window as any).webkitSpeechRecognition;
|
|
363
|
+
setIsVoiceSupported(!!SR);
|
|
364
|
+
} catch {
|
|
365
|
+
setIsVoiceSupported(false);
|
|
366
|
+
}
|
|
367
|
+
}, []);
|
|
368
|
+
|
|
369
|
+
// Start voice recognition
|
|
370
|
+
const startVoice = useCallback(() => {
|
|
371
|
+
try {
|
|
372
|
+
if (isListening) return;
|
|
373
|
+
if (typeof window === "undefined") return;
|
|
374
|
+
const SR: any =
|
|
375
|
+
(window as any).SpeechRecognition ||
|
|
376
|
+
(window as any).webkitSpeechRecognition;
|
|
377
|
+
if (!SR) {
|
|
378
|
+
setVoiceError("Voice input is not supported in this browser");
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
const r = new SR();
|
|
382
|
+
r.lang = (editContext?.currentItemDescriptor?.language as any) || "en-US";
|
|
383
|
+
r.continuous = true;
|
|
384
|
+
r.interimResults = true;
|
|
385
|
+
r.onstart = () => {
|
|
386
|
+
setIsListening(true);
|
|
387
|
+
prevPlaceholderRef.current = inputPlaceholder;
|
|
388
|
+
setVoiceError(null);
|
|
389
|
+
setInputPlaceholder("Listening...");
|
|
390
|
+
};
|
|
391
|
+
r.onresult = (event: any) => {
|
|
392
|
+
let finalText = "";
|
|
393
|
+
let interimText = "";
|
|
394
|
+
for (let i = event.resultIndex; i < event.results.length; i++) {
|
|
395
|
+
const res = event.results[i];
|
|
396
|
+
if (res.isFinal) finalText += res[0]?.transcript || "";
|
|
397
|
+
else interimText += res[0]?.transcript || "";
|
|
398
|
+
}
|
|
399
|
+
if (interimText) {
|
|
400
|
+
setInputPlaceholder(`Listening... ${interimText.trim()}`);
|
|
401
|
+
} else {
|
|
402
|
+
setInputPlaceholder("Listening...");
|
|
403
|
+
}
|
|
404
|
+
if (finalText && finalText.trim()) {
|
|
405
|
+
setPrompt((prev) => {
|
|
406
|
+
const prefix = prev && !prev.endsWith(" ") ? prev + " " : prev;
|
|
407
|
+
return (prefix || "") + finalText.trim() + " ";
|
|
408
|
+
});
|
|
409
|
+
if (textareaRef.current) {
|
|
410
|
+
try {
|
|
411
|
+
const v = textareaRef.current.value || "";
|
|
412
|
+
textareaRef.current.selectionStart = v.length;
|
|
413
|
+
textareaRef.current.selectionEnd = v.length;
|
|
414
|
+
} catch {}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
r.onerror = (e: any) => {
|
|
419
|
+
console.warn("Speech recognition error", e);
|
|
420
|
+
setVoiceError(e?.error || "Voice input error");
|
|
421
|
+
};
|
|
422
|
+
r.onend = () => {
|
|
423
|
+
setIsListening(false);
|
|
424
|
+
if (prevPlaceholderRef.current !== null) {
|
|
425
|
+
setInputPlaceholder(prevPlaceholderRef.current);
|
|
426
|
+
prevPlaceholderRef.current = null;
|
|
427
|
+
}
|
|
428
|
+
recognitionRef.current = null;
|
|
429
|
+
};
|
|
430
|
+
recognitionRef.current = r;
|
|
431
|
+
r.start();
|
|
432
|
+
} catch (e) {
|
|
433
|
+
console.error("Failed to start voice input", e);
|
|
434
|
+
setVoiceError("Failed to start voice input");
|
|
435
|
+
}
|
|
436
|
+
}, [
|
|
437
|
+
editContext?.currentItemDescriptor?.language,
|
|
438
|
+
inputPlaceholder,
|
|
439
|
+
isListening,
|
|
440
|
+
]);
|
|
441
|
+
|
|
442
|
+
const stopVoice = useCallback(() => {
|
|
443
|
+
try {
|
|
444
|
+
const r = recognitionRef.current;
|
|
445
|
+
if (r) r.stop();
|
|
446
|
+
} catch {}
|
|
447
|
+
}, []);
|
|
448
|
+
|
|
449
|
+
const toggleVoice = useCallback(() => {
|
|
450
|
+
if (isListening) stopVoice();
|
|
451
|
+
else startVoice();
|
|
452
|
+
}, [isListening, startVoice, stopVoice]);
|
|
453
|
+
|
|
454
|
+
// Cleanup any active recognition on unmount
|
|
455
|
+
useEffect(() => {
|
|
456
|
+
return () => {
|
|
457
|
+
try {
|
|
458
|
+
const r = recognitionRef.current;
|
|
459
|
+
if (r) {
|
|
460
|
+
r.onresult = null;
|
|
461
|
+
r.onerror = null;
|
|
462
|
+
r.onend = null;
|
|
463
|
+
r.stop();
|
|
464
|
+
}
|
|
465
|
+
} catch {}
|
|
466
|
+
recognitionRef.current = null;
|
|
467
|
+
};
|
|
468
|
+
}, []);
|
|
469
|
+
|
|
340
470
|
// Check if user is at the bottom of the scroll container
|
|
341
471
|
const isAtBottom = useCallback(() => {
|
|
342
472
|
const container = messagesContainerRef.current;
|
|
@@ -1240,22 +1370,31 @@ export function AgentTerminal({
|
|
|
1240
1370
|
const metaMode = (agentMetadata as any)?.mode as
|
|
1241
1371
|
| "agent"
|
|
1242
1372
|
| "ask"
|
|
1373
|
+
| "restricted"
|
|
1243
1374
|
| undefined;
|
|
1244
|
-
if (
|
|
1375
|
+
if (
|
|
1376
|
+
metaMode === "agent" ||
|
|
1377
|
+
metaMode === "ask" ||
|
|
1378
|
+
metaMode === "restricted"
|
|
1379
|
+
) {
|
|
1245
1380
|
setMode(metaMode);
|
|
1246
1381
|
return;
|
|
1247
1382
|
}
|
|
1248
1383
|
} catch {}
|
|
1249
1384
|
try {
|
|
1250
1385
|
const serverMode = (agent as any)?.mode as string | undefined;
|
|
1251
|
-
if (
|
|
1386
|
+
if (
|
|
1387
|
+
serverMode === "agent" ||
|
|
1388
|
+
serverMode === "ask" ||
|
|
1389
|
+
serverMode === "restricted"
|
|
1390
|
+
) {
|
|
1252
1391
|
setMode(serverMode);
|
|
1253
1392
|
}
|
|
1254
1393
|
} catch {}
|
|
1255
1394
|
}, [agentMetadata, (agent as any)?.mode]);
|
|
1256
1395
|
|
|
1257
1396
|
const updateMode = useCallback(
|
|
1258
|
-
async (nextMode:
|
|
1397
|
+
async (nextMode: AgentMode) => {
|
|
1259
1398
|
setMode(nextMode);
|
|
1260
1399
|
const current = agentMetadata || ({} as AgentMetadata);
|
|
1261
1400
|
const nextMeta: AgentMetadata = {
|
|
@@ -1305,7 +1444,7 @@ export function AgentTerminal({
|
|
|
1305
1444
|
if (!pending) return;
|
|
1306
1445
|
const payload: {
|
|
1307
1446
|
model?: string | null;
|
|
1308
|
-
mode?:
|
|
1447
|
+
mode?: AgentMode | string | null;
|
|
1309
1448
|
} = {};
|
|
1310
1449
|
if (pending.modelName) payload.model = pending.modelName;
|
|
1311
1450
|
if (pending.mode) payload.mode = pending.mode;
|
|
@@ -1393,7 +1532,7 @@ export function AgentTerminal({
|
|
|
1393
1532
|
version: editContext.currentItemDescriptor?.version || 1,
|
|
1394
1533
|
selection: effectiveSelection,
|
|
1395
1534
|
selectedText: selectedTextFromCtx,
|
|
1396
|
-
mode: mode,
|
|
1535
|
+
mode: mode as any,
|
|
1397
1536
|
allowedFunctions:
|
|
1398
1537
|
mode === "ask"
|
|
1399
1538
|
? activeProfile?.askModeTools &&
|
|
@@ -1572,7 +1711,7 @@ export function AgentTerminal({
|
|
|
1572
1711
|
version: editContext.currentItemDescriptor?.version || 1,
|
|
1573
1712
|
selection: effectiveSelection,
|
|
1574
1713
|
selectedText: selectedTextFromCtx,
|
|
1575
|
-
mode: mode,
|
|
1714
|
+
mode: mode as any,
|
|
1576
1715
|
allowedFunctions:
|
|
1577
1716
|
mode === "ask"
|
|
1578
1717
|
? activeProfile?.askModeTools &&
|
|
@@ -2369,6 +2508,7 @@ export function AgentTerminal({
|
|
|
2369
2508
|
aria-label="Mode"
|
|
2370
2509
|
data-testid="agent-mode-select"
|
|
2371
2510
|
>
|
|
2511
|
+
<option value="restricted">Restricted</option>
|
|
2372
2512
|
<option value="agent">Agent</option>
|
|
2373
2513
|
<option value="ask">Ask</option>
|
|
2374
2514
|
</select>
|
|
@@ -2461,22 +2601,46 @@ export function AgentTerminal({
|
|
|
2461
2601
|
</PopoverContent>
|
|
2462
2602
|
</Popover>
|
|
2463
2603
|
) : null}
|
|
2464
|
-
<AgentCostDisplay totalTokens={totalTokens} />
|
|
2465
2604
|
</div>
|
|
2466
|
-
<
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2605
|
+
<div className="flex items-center gap-1 self-end">
|
|
2606
|
+
{isVoiceSupported ? (
|
|
2607
|
+
<Button
|
|
2608
|
+
onClick={toggleVoice}
|
|
2609
|
+
size="sm"
|
|
2610
|
+
className="h-5.5 w-5.5 cursor-pointer rounded-full"
|
|
2611
|
+
title={isListening ? "Stop voice input" : "Start voice input"}
|
|
2612
|
+
aria-label={
|
|
2613
|
+
isListening ? "Stop voice input" : "Start voice input"
|
|
2614
|
+
}
|
|
2615
|
+
aria-pressed={isListening}
|
|
2616
|
+
>
|
|
2617
|
+
{isListening ? (
|
|
2618
|
+
<MicOff className="size-3" strokeWidth={1} />
|
|
2619
|
+
) : (
|
|
2620
|
+
<Mic className="size-3" strokeWidth={1} />
|
|
2621
|
+
)}
|
|
2622
|
+
</Button>
|
|
2623
|
+
) : null}
|
|
2624
|
+
<Button
|
|
2625
|
+
onClick={isExecuting ? handleStop : handleSubmit}
|
|
2626
|
+
disabled={!isExecuting && !prompt.trim()}
|
|
2627
|
+
size="sm"
|
|
2628
|
+
className="h-5.5 w-5.5 cursor-pointer rounded-full"
|
|
2629
|
+
title={isExecuting ? "Stop" : "Send"}
|
|
2630
|
+
aria-label={isExecuting ? "Stop" : "Send"}
|
|
2631
|
+
data-testid="agent-send-stop-button"
|
|
2632
|
+
data-executing={isExecuting ? "true" : "false"}
|
|
2633
|
+
>
|
|
2634
|
+
{isExecuting ? (
|
|
2635
|
+
<Square className="size-3" strokeWidth={1} />
|
|
2636
|
+
) : (
|
|
2637
|
+
<Send className="size-3" strokeWidth={1} />
|
|
2638
|
+
)}
|
|
2639
|
+
</Button>
|
|
2640
|
+
</div>
|
|
2641
|
+
</div>
|
|
2642
|
+
<div className="mt-1 flex justify-start">
|
|
2643
|
+
<AgentCostDisplay totalTokens={totalTokens} />
|
|
2480
2644
|
</div>
|
|
2481
2645
|
</div>
|
|
2482
2646
|
</div>
|
package/src/editor/ai/Agents.tsx
CHANGED
|
@@ -545,7 +545,7 @@ export function Agents({ closeButton }: { closeButton?: React.ReactNode }) {
|
|
|
545
545
|
<div
|
|
546
546
|
key={agent.id}
|
|
547
547
|
className={cn(
|
|
548
|
-
"flex min-w-0 cursor-pointer items-center gap-1 border-r border-gray-200 px-
|
|
548
|
+
"flex min-w-0 cursor-pointer items-center gap-1 border-r border-gray-200 px-2 py-2 pr-1.5 text-xs",
|
|
549
549
|
activeAgentId === agent.id
|
|
550
550
|
? "border-b-white bg-white"
|
|
551
551
|
: "hover:bg-gray-100",
|
|
@@ -594,7 +594,7 @@ export function Agents({ closeButton }: { closeButton?: React.ReactNode }) {
|
|
|
594
594
|
e.stopPropagation();
|
|
595
595
|
closeAgent(agent.id);
|
|
596
596
|
}}
|
|
597
|
-
icon={<X className="size-
|
|
597
|
+
icon={<X className="size-3" strokeWidth={1} />}
|
|
598
598
|
label="Close"
|
|
599
599
|
className="ml-1 opacity-60 hover:opacity-100"
|
|
600
600
|
/>
|
|
@@ -537,9 +537,11 @@ export function ContextInfoBar({
|
|
|
537
537
|
/>
|
|
538
538
|
</div>
|
|
539
539
|
{!isCollapsed && (
|
|
540
|
-
<div className="flex
|
|
541
|
-
<div className="flex
|
|
542
|
-
|
|
540
|
+
<div className="flex flex-col gap-2">
|
|
541
|
+
<div className="flex items-center justify-between text-xs text-gray-600">
|
|
542
|
+
<div className="flex flex-wrap items-center gap-2">{chips}</div>
|
|
543
|
+
</div>
|
|
544
|
+
<div className="flex flex-col items-start gap-1">
|
|
543
545
|
{canAddPage && (
|
|
544
546
|
<Button size="xs" variant="outline" onClick={addPagesToContext}>
|
|
545
547
|
<Plus className="mr-1 h-3 w-3" strokeWidth={1} /> Add current
|
|
@@ -556,9 +558,9 @@ export function ContextInfoBar({
|
|
|
556
558
|
components
|
|
557
559
|
</Button>
|
|
558
560
|
)}
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
561
|
+
</div>
|
|
562
|
+
<div className="text-2xs text-gray-400">
|
|
563
|
+
Tip: Drag items or components here to add them
|
|
562
564
|
</div>
|
|
563
565
|
</div>
|
|
564
566
|
)}
|
|
@@ -142,6 +142,7 @@ import { FullscreenControls } from "./ui/FullscreenControls";
|
|
|
142
142
|
import { EditorChrome } from "./ui/EditorChrome";
|
|
143
143
|
import { useWorkbox } from "./hooks/useWorkbox";
|
|
144
144
|
import { useMediaSelector } from "./hooks/useMediaSelector";
|
|
145
|
+
import { useGlobalEditorKeyDown } from "./hooks/useGlobalEditorKeyDown";
|
|
145
146
|
|
|
146
147
|
export type FieldAction = {
|
|
147
148
|
field: FieldDescriptor;
|
|
@@ -1525,6 +1526,8 @@ export function EditorShell({
|
|
|
1525
1526
|
executeCommand,
|
|
1526
1527
|
});
|
|
1527
1528
|
|
|
1529
|
+
useGlobalEditorKeyDown(handleKeyDown);
|
|
1530
|
+
|
|
1528
1531
|
useEffect(() => {
|
|
1529
1532
|
const handleGlobalBlur = () => {
|
|
1530
1533
|
operations.onFieldBlur?.();
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
Dialog,
|
|
3
|
+
DialogContent,
|
|
4
|
+
DialogHeader,
|
|
5
|
+
DialogTitle,
|
|
6
|
+
} from "../../components/ui/dialog";
|
|
3
7
|
import { forwardRef, useImperativeHandle, useState } from "react";
|
|
4
8
|
|
|
5
9
|
export interface GenericDialogHandle {
|
|
@@ -38,13 +42,13 @@ export const GenericDialog = forwardRef<GenericDialogHandle>((_, ref) => {
|
|
|
38
42
|
}));
|
|
39
43
|
|
|
40
44
|
return (
|
|
41
|
-
<Dialog
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
<Dialog open={visible} onOpenChange={(open) => !open && setVisible(false)}>
|
|
46
|
+
<DialogContent className="max-w-none" style={{ width, height }}>
|
|
47
|
+
<DialogHeader>
|
|
48
|
+
<DialogTitle>{title}</DialogTitle>
|
|
49
|
+
</DialogHeader>
|
|
50
|
+
<div className="flex-1 overflow-auto p-6">{content}</div>
|
|
51
|
+
</DialogContent>
|
|
48
52
|
</Dialog>
|
|
49
53
|
);
|
|
50
54
|
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
|
|
3
|
+
export function useGlobalEditorKeyDown(onKeyDown: (ev: KeyboardEvent) => void) {
|
|
4
|
+
useEffect(() => {
|
|
5
|
+
if (typeof window === "undefined") return;
|
|
6
|
+
window.addEventListener("keydown", onKeyDown, true);
|
|
7
|
+
return () => {
|
|
8
|
+
window.removeEventListener("keydown", onKeyDown, true);
|
|
9
|
+
};
|
|
10
|
+
}, [onKeyDown]);
|
|
11
|
+
}
|
|
@@ -34,7 +34,7 @@ export function EditorChrome(props: {
|
|
|
34
34
|
centerPanelView={centerPanelView}
|
|
35
35
|
rightSidebar={
|
|
36
36
|
currentView.rightSidebar &&
|
|
37
|
-
editContext.page &&
|
|
37
|
+
(editContext.page || editContext.contentEditorItem?.hasLayout) &&
|
|
38
38
|
showComponentNavigator && (
|
|
39
39
|
<SidebarView
|
|
40
40
|
sidebar={currentView.rightSidebar}
|
|
@@ -49,9 +49,13 @@ export function EditorChrome(props: {
|
|
|
49
49
|
farRightSidebar={
|
|
50
50
|
showAgentsPanel &&
|
|
51
51
|
!editContext.currentWizardId &&
|
|
52
|
-
![
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
![
|
|
53
|
+
"splash-screen",
|
|
54
|
+
"open-page",
|
|
55
|
+
"new-page",
|
|
56
|
+
"page-wizard",
|
|
57
|
+
"control-center",
|
|
58
|
+
].includes(viewName) && (
|
|
55
59
|
<SidebarView
|
|
56
60
|
sidebar={{
|
|
57
61
|
title: "Agents",
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import { Button } from "
|
|
2
|
-
import {
|
|
1
|
+
import { Button } from "../../../components/ui/button";
|
|
2
|
+
import {
|
|
3
|
+
Dialog,
|
|
4
|
+
DialogContent,
|
|
5
|
+
DialogHeader,
|
|
6
|
+
DialogTitle,
|
|
7
|
+
} from "../../../components/ui/dialog";
|
|
3
8
|
import { useEffect, useState } from "react";
|
|
4
9
|
import DialogButtons from "../../ui/DialogButtons";
|
|
5
10
|
import { DialogProps } from "../../client/editContext";
|
|
@@ -119,7 +124,9 @@ export function LocalizeItemDialog(
|
|
|
119
124
|
</div>
|
|
120
125
|
)}
|
|
121
126
|
<DialogButtons>
|
|
122
|
-
<Button onClick={() => props.onClose?.(null)}
|
|
127
|
+
<Button onClick={() => props.onClose?.(null)} size="sm">
|
|
128
|
+
Close
|
|
129
|
+
</Button>
|
|
123
130
|
</DialogButtons>
|
|
124
131
|
</div>
|
|
125
132
|
);
|
|
@@ -179,8 +186,12 @@ export function LocalizeItemDialog(
|
|
|
179
186
|
</div>
|
|
180
187
|
</div>
|
|
181
188
|
<DialogButtons>
|
|
182
|
-
<Button onClick={startLocalization}
|
|
183
|
-
|
|
189
|
+
<Button onClick={startLocalization} size="sm">
|
|
190
|
+
Start
|
|
191
|
+
</Button>
|
|
192
|
+
<Button onClick={() => props.onClose?.(null)} size="sm">
|
|
193
|
+
Cancel
|
|
194
|
+
</Button>
|
|
184
195
|
</DialogButtons>
|
|
185
196
|
</div>
|
|
186
197
|
);
|
|
@@ -188,14 +199,22 @@ export function LocalizeItemDialog(
|
|
|
188
199
|
|
|
189
200
|
return (
|
|
190
201
|
<Dialog
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
202
|
+
open={true}
|
|
203
|
+
onOpenChange={(open) => {
|
|
204
|
+
if (!open) {
|
|
205
|
+
props.onClose?.(null);
|
|
206
|
+
}
|
|
194
207
|
}}
|
|
195
|
-
style={{ width: "75vw", height: "75vh" }}
|
|
196
|
-
header="Localize"
|
|
197
208
|
>
|
|
198
|
-
|
|
209
|
+
<DialogContent
|
|
210
|
+
className="max-w-none"
|
|
211
|
+
style={{ width: "75vw", height: "75vh" }}
|
|
212
|
+
>
|
|
213
|
+
<DialogHeader>
|
|
214
|
+
<DialogTitle>Localize</DialogTitle>
|
|
215
|
+
</DialogHeader>
|
|
216
|
+
<div className="flex-1 overflow-auto">{dialogContent}</div>
|
|
217
|
+
</DialogContent>
|
|
199
218
|
</Dialog>
|
|
200
219
|
);
|
|
201
220
|
}
|
|
@@ -3,7 +3,7 @@ import { useEditContext } from "../client/editContext";
|
|
|
3
3
|
import { MoveCopyItemsCommand } from "../commands/itemCommands";
|
|
4
4
|
import { FullItem, ItemDescriptor } from "../pageModel";
|
|
5
5
|
import { ScrollingContentTree } from "../ScrollingContentTree";
|
|
6
|
-
import { Button } from "
|
|
6
|
+
import { Button } from "../../components/ui/button";
|
|
7
7
|
|
|
8
8
|
export const CopyMoveMenuTemplate = ({
|
|
9
9
|
items,
|
|
@@ -85,7 +85,7 @@ export const CopyMoveMenuTemplate = ({
|
|
|
85
85
|
</div>
|
|
86
86
|
<div className="flex justify-end">
|
|
87
87
|
<Button
|
|
88
|
-
|
|
88
|
+
size="sm"
|
|
89
89
|
onClick={() => {
|
|
90
90
|
if (!selectedItem) return;
|
|
91
91
|
const result = editContext?.executeCommand({
|
|
@@ -94,7 +94,9 @@ export const CopyMoveMenuTemplate = ({
|
|
|
94
94
|
});
|
|
95
95
|
commandCallback?.(command, result);
|
|
96
96
|
}}
|
|
97
|
-
|
|
97
|
+
>
|
|
98
|
+
{mode === "copy" ? "Copy" : "Move"}
|
|
99
|
+
</Button>
|
|
98
100
|
</div>
|
|
99
101
|
</div>
|
|
100
102
|
</div>
|