@agent-native/toolkit 0.225.1 → 0.226.0-nightly-20261106182619
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/agent-native.eject.json +1 -0
- package/dist/app/agentkit/react/components.d.ts.map +1 -1
- package/dist/app/agentkit/react/components.js +124 -9
- package/dist/app/agentkit/react/components.js.map +1 -1
- package/dist/app/agentkit/react/context.d.ts +1 -1
- package/dist/app/agentkit/react/core-file-storage.d.ts +21 -0
- package/dist/app/agentkit/react/core-file-storage.d.ts.map +1 -0
- package/dist/app/agentkit/react/core-file-storage.js +3 -0
- package/dist/app/agentkit/react/core-file-storage.js.map +1 -0
- package/dist/app/auth/AuthPage.d.ts.map +1 -1
- package/dist/app/auth/AuthPage.js +89 -10
- package/dist/app/auth/AuthPage.js.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.js +39 -58
- package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
- package/dist/app/chat/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/MultiTabAssistantChat.js +3 -1
- package/dist/app/chat/MultiTabAssistantChat.js.map +1 -1
- package/dist/app/chat/agentkit-chat/root.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/root.js +66 -2
- package/dist/app/chat/agentkit-chat/root.js.map +1 -1
- package/dist/app/chat/chat/surface-types.d.ts +1 -0
- package/dist/app/chat/chat/surface-types.d.ts.map +1 -1
- package/dist/app/chat/chat/surface-types.js.map +1 -1
- package/dist/app/chat/composer/runtime-adapters.d.ts.map +1 -1
- package/dist/app/chat/composer/runtime-adapters.js +2 -0
- package/dist/app/chat/composer/runtime-adapters.js.map +1 -1
- package/dist/app/chat/composer/use-agentkit-capabilities.d.ts +3 -1
- package/dist/app/chat/composer/use-agentkit-capabilities.d.ts.map +1 -1
- package/dist/app/chat/composer/use-agentkit-capabilities.js +11 -11
- package/dist/app/chat/composer/use-agentkit-capabilities.js.map +1 -1
- package/dist/app/chat/composer/use-workspace-composer-menu.d.ts +3 -0
- package/dist/app/chat/composer/use-workspace-composer-menu.d.ts.map +1 -0
- package/dist/app/chat/composer/use-workspace-composer-menu.js +80 -0
- package/dist/app/chat/composer/use-workspace-composer-menu.js.map +1 -0
- package/dist/app/chat/index.d.ts +1 -0
- package/dist/app/chat/index.d.ts.map +1 -1
- package/dist/app/chat/index.js +1 -0
- package/dist/app/chat/index.js.map +1 -1
- package/dist/app/chat/prepare-prompt-composer-agent-handoff.d.ts +5 -0
- package/dist/app/chat/prepare-prompt-composer-agent-handoff.d.ts.map +1 -0
- package/dist/app/chat/prepare-prompt-composer-agent-handoff.js +108 -0
- package/dist/app/chat/prepare-prompt-composer-agent-handoff.js.map +1 -0
- package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.js +6 -1
- package/dist/app/i18n/catalogs/ar-SA.js.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.js +6 -1
- package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
- package/dist/app/i18n/catalogs/en-US.d.ts +6 -1
- package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/en-US.js +6 -1
- package/dist/app/i18n/catalogs/en-US.js.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.js +6 -1
- package/dist/app/i18n/catalogs/es-ES.js.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.js +6 -1
- package/dist/app/i18n/catalogs/fr-FR.js.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.js +6 -1
- package/dist/app/i18n/catalogs/hi-IN.js.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.js +6 -1
- package/dist/app/i18n/catalogs/ja-JP.js.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.js +6 -1
- package/dist/app/i18n/catalogs/ko-KR.js.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.js +6 -1
- package/dist/app/i18n/catalogs/pt-BR.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.js +6 -1
- package/dist/app/i18n/catalogs/zh-CN.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.js +6 -1
- package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
- package/dist/app/resources/McpIntegrationDialog.d.ts +3 -1
- package/dist/app/resources/McpIntegrationDialog.d.ts.map +1 -1
- package/dist/app/resources/McpIntegrationDialog.js +2 -2
- package/dist/app/resources/McpIntegrationDialog.js.map +1 -1
- package/dist/app/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/app/settings/useBuilderStatus.js +119 -40
- package/dist/app/settings/useBuilderStatus.js.map +1 -1
- package/dist/composer/ComposerContextMenu.d.ts +36 -2
- package/dist/composer/ComposerContextMenu.d.ts.map +1 -1
- package/dist/composer/ComposerContextMenu.js +108 -40
- package/dist/composer/ComposerContextMenu.js.map +1 -1
- package/dist/composer/ComposerContextPickerDialog.d.ts.map +1 -1
- package/dist/composer/ComposerContextPickerDialog.js +63 -26
- package/dist/composer/ComposerContextPickerDialog.js.map +1 -1
- package/dist/composer/ComposerPlusMenu.d.ts +5 -3
- package/dist/composer/ComposerPlusMenu.d.ts.map +1 -1
- package/dist/composer/ComposerPlusMenu.js +166 -121
- package/dist/composer/ComposerPlusMenu.js.map +1 -1
- package/dist/composer/MentionItemMedia.d.ts.map +1 -1
- package/dist/composer/MentionItemMedia.js +3 -1
- package/dist/composer/MentionItemMedia.js.map +1 -1
- package/dist/composer/PromptComposer.d.ts +1 -0
- package/dist/composer/PromptComposer.d.ts.map +1 -1
- package/dist/composer/PromptComposer.js +1 -0
- package/dist/composer/PromptComposer.js.map +1 -1
- package/dist/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/composer/TiptapComposer.js +117 -50
- package/dist/composer/TiptapComposer.js.map +1 -1
- package/dist/composer/index.d.ts +1 -0
- package/dist/composer/index.d.ts.map +1 -1
- package/dist/composer/runtime-adapters.d.ts +15 -0
- package/dist/composer/runtime-adapters.d.ts.map +1 -1
- package/dist/composer/runtime-adapters.js.map +1 -1
- package/dist/composer/use-composer-panel-placement.d.ts.map +1 -1
- package/dist/composer/use-composer-panel-placement.js +2 -4
- package/dist/composer/use-composer-panel-placement.js.map +1 -1
- package/dist/composer/use-mention-search.d.ts +7 -0
- package/dist/composer/use-mention-search.d.ts.map +1 -1
- package/dist/composer/use-mention-search.js +86 -19
- package/dist/composer/use-mention-search.js.map +1 -1
- package/dist/composer/useComposerContextPicker.d.ts +5 -1
- package/dist/composer/useComposerContextPicker.d.ts.map +1 -1
- package/dist/composer/useComposerContextPicker.js +18 -4
- package/dist/composer/useComposerContextPicker.js.map +1 -1
- package/package.json +4 -4
- package/src/app/agentkit/react/components.tsx +158 -11
- package/src/app/agentkit/react/composer-context.spec.tsx +180 -0
- package/src/app/agentkit/react/core-file-storage.tsx +14 -0
- package/src/app/auth/AuthPage.interaction.spec.tsx +143 -0
- package/src/app/auth/AuthPage.tsx +159 -13
- package/src/app/chat/AgentKitAssistantChat.spec.tsx +65 -3
- package/src/app/chat/AgentKitAssistantChat.tsx +57 -65
- package/src/app/chat/MultiTabAssistantChat.spec.tsx +21 -0
- package/src/app/chat/MultiTabAssistantChat.tsx +4 -0
- package/src/app/chat/agentkit-chat/root.tsx +91 -8
- package/src/app/chat/chat/surface-types.ts +1 -0
- package/src/app/chat/composer/runtime-adapters.tsx +2 -0
- package/src/app/chat/composer/use-agentkit-capabilities.hardening.spec.tsx +26 -1
- package/src/app/chat/composer/use-agentkit-capabilities.ts +11 -11
- package/src/app/chat/composer/use-agentkit-integration-menu.spec.tsx +2 -4
- package/src/app/chat/composer/use-workspace-composer-menu.spec.tsx +174 -0
- package/src/app/chat/composer/use-workspace-composer-menu.tsx +122 -0
- package/src/app/chat/index.ts +1 -0
- package/src/app/chat/prepare-prompt-composer-agent-handoff.spec.ts +162 -0
- package/src/app/chat/prepare-prompt-composer-agent-handoff.ts +134 -0
- package/src/app/i18n/catalogs/ar-SA.ts +6 -1
- package/src/app/i18n/catalogs/de-DE.ts +6 -1
- package/src/app/i18n/catalogs/en-US.ts +6 -1
- package/src/app/i18n/catalogs/es-ES.ts +6 -1
- package/src/app/i18n/catalogs/fr-FR.ts +6 -1
- package/src/app/i18n/catalogs/hi-IN.ts +6 -1
- package/src/app/i18n/catalogs/ja-JP.ts +6 -1
- package/src/app/i18n/catalogs/ko-KR.ts +6 -1
- package/src/app/i18n/catalogs/pt-BR.ts +6 -1
- package/src/app/i18n/catalogs/zh-CN.ts +6 -1
- package/src/app/i18n/catalogs/zh-TW.ts +6 -1
- package/src/app/resources/McpIntegrationDialog.tsx +5 -0
- package/src/app/settings/useBuilderStatus.spec.tsx +229 -13
- package/src/app/settings/useBuilderStatus.ts +145 -47
- package/src/composer/ComposerContextMenu.spec.tsx +95 -32
- package/src/composer/ComposerContextMenu.tsx +284 -73
- package/src/composer/ComposerContextPicker.spec.tsx +13 -14
- package/src/composer/ComposerContextPickerDialog.spec.tsx +40 -3
- package/src/composer/ComposerContextPickerDialog.tsx +158 -24
- package/src/composer/ComposerPlusMenu.parity.spec.tsx +442 -62
- package/src/composer/ComposerPlusMenu.tsx +322 -237
- package/src/composer/MentionItemMedia.tsx +3 -0
- package/src/composer/PromptComposer.context.spec.tsx +253 -82
- package/src/composer/PromptComposer.tsx +2 -0
- package/src/composer/TiptapComposer.spec.ts +6 -8
- package/src/composer/TiptapComposer.tsx +148 -55
- package/src/composer/index.ts +5 -0
- package/src/composer/runtime-adapters.tsx +18 -0
- package/src/composer/use-composer-panel-placement.ts +2 -4
- package/src/composer/use-mention-search.spec.tsx +99 -1
- package/src/composer/use-mention-search.ts +101 -24
- package/src/composer/useComposerContextPicker.ts +25 -5
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import { useComposerRuntime } from "@assistant-ui/react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
IconBolt,
|
|
4
|
+
IconCalendarTime,
|
|
5
|
+
IconCode,
|
|
6
|
+
IconLoader2,
|
|
7
|
+
IconPlugConnected,
|
|
8
|
+
IconSchool,
|
|
9
|
+
} from "@tabler/icons-react";
|
|
3
10
|
import { useCallback, useEffect, useId, useRef, useState } from "react";
|
|
4
11
|
|
|
5
12
|
import { uploadedSkillSlug } from "../skill-upload.js";
|
|
6
13
|
import { Button } from "../ui/button.js";
|
|
7
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
Dialog,
|
|
16
|
+
DialogContent,
|
|
17
|
+
DialogHeader,
|
|
18
|
+
DialogTitle,
|
|
19
|
+
} from "../ui/dialog.js";
|
|
8
20
|
import { Input } from "../ui/input.js";
|
|
9
21
|
import { Label } from "../ui/label.js";
|
|
10
22
|
import { Textarea } from "../ui/textarea.js";
|
|
@@ -14,9 +26,11 @@ import {
|
|
|
14
26
|
ComposerContextMenu,
|
|
15
27
|
type ComposerContextMenuItem,
|
|
16
28
|
type ComposerContextMenuProps,
|
|
17
|
-
type ComposerContextPageControls,
|
|
18
29
|
} from "./ComposerContextMenu.js";
|
|
19
|
-
import {
|
|
30
|
+
import {
|
|
31
|
+
useComposerRuntimeAdapters,
|
|
32
|
+
type AgentComposerReference,
|
|
33
|
+
} from "./runtime-adapters.js";
|
|
20
34
|
import type { ComposerMode } from "./types.js";
|
|
21
35
|
|
|
22
36
|
export interface ComposerTerminalModeControl {
|
|
@@ -29,6 +43,7 @@ interface ComposerPlusMenuProps extends Omit<
|
|
|
29
43
|
ComposerContextMenuProps,
|
|
30
44
|
"items"
|
|
31
45
|
> {
|
|
46
|
+
onSelectIntegration?: (reference: AgentComposerReference) => void;
|
|
32
47
|
onSelectMode?: (mode: ComposerMode) => void;
|
|
33
48
|
attachmentsEnabled?: boolean;
|
|
34
49
|
extensionTools?: boolean;
|
|
@@ -58,15 +73,46 @@ export function mergeComposerMenuItems(
|
|
|
58
73
|
defaults: readonly ComposerContextMenuItem[],
|
|
59
74
|
provided: readonly ComposerContextMenuItem[],
|
|
60
75
|
): ComposerContextMenuItem[] {
|
|
61
|
-
const
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
76
|
+
const defaultIds = new Set(defaults.map((item) => item.id));
|
|
77
|
+
const overrides = new Map<string, ComposerContextMenuItem>();
|
|
78
|
+
const seen = new Set<string>();
|
|
79
|
+
const retain = (
|
|
80
|
+
items: readonly ComposerContextMenuItem[],
|
|
81
|
+
inheritedDisabled = false,
|
|
82
|
+
): ComposerContextMenuItem[] =>
|
|
83
|
+
items.flatMap((item): ComposerContextMenuItem[] => {
|
|
84
|
+
if (seen.has(item.id)) return [];
|
|
85
|
+
seen.add(item.id);
|
|
86
|
+
if (defaultIds.has(item.id)) {
|
|
87
|
+
overrides.set(
|
|
88
|
+
item.id,
|
|
89
|
+
inheritedDisabled ? { ...item, disabled: true } : item,
|
|
90
|
+
);
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
if (!item.children) return [item];
|
|
94
|
+
const children = retain(
|
|
95
|
+
item.children,
|
|
96
|
+
inheritedDisabled || item.disabled === true,
|
|
97
|
+
);
|
|
98
|
+
return children.length ? [{ ...item, children }] : [];
|
|
99
|
+
});
|
|
100
|
+
const context = retain(provided);
|
|
101
|
+
return [
|
|
102
|
+
...context,
|
|
103
|
+
...defaults.map((item) => {
|
|
104
|
+
const override = overrides.get(item.id);
|
|
105
|
+
const section = override?.section ?? item.section;
|
|
106
|
+
return override
|
|
107
|
+
? {
|
|
108
|
+
...override,
|
|
109
|
+
...(item.order === undefined ? {} : { order: item.order }),
|
|
110
|
+
...(section === undefined ? {} : { section }),
|
|
111
|
+
icon: override.icon ?? item.icon,
|
|
112
|
+
}
|
|
113
|
+
: item;
|
|
114
|
+
}),
|
|
115
|
+
];
|
|
70
116
|
}
|
|
71
117
|
|
|
72
118
|
export function useComposerDefaultActions({
|
|
@@ -74,16 +120,22 @@ export function useComposerDefaultActions({
|
|
|
74
120
|
extensionTools = false,
|
|
75
121
|
disabled,
|
|
76
122
|
onRestoreFocus,
|
|
123
|
+
integrationStatus,
|
|
77
124
|
}: Pick<
|
|
78
125
|
ComposerPlusMenuProps,
|
|
79
|
-
|
|
126
|
+
| "onSelectMode"
|
|
127
|
+
| "extensionTools"
|
|
128
|
+
| "disabled"
|
|
129
|
+
| "onRestoreFocus"
|
|
130
|
+
| "integrationStatus"
|
|
80
131
|
>) {
|
|
81
132
|
const adapters = useComposerRuntimeAdapters();
|
|
82
|
-
const t = adapters.translate
|
|
133
|
+
const t = adapters.translate;
|
|
83
134
|
const resources = adapters.resources!;
|
|
84
135
|
const [mcpDialogOpen, setMcpDialogOpen] = useState(false);
|
|
85
|
-
const
|
|
86
|
-
|
|
136
|
+
const showMcpIntegrations =
|
|
137
|
+
!resources.useWorkspaceMenu &&
|
|
138
|
+
resources.isMcpIntegrationAvailable?.() === true;
|
|
87
139
|
const { data: org } = resources.useOrg!();
|
|
88
140
|
const canCreateOrgMcp =
|
|
89
141
|
!org?.orgId || org.role === "owner" || org.role === "admin";
|
|
@@ -91,10 +143,6 @@ export function useComposerDefaultActions({
|
|
|
91
143
|
const McpIntegrationDialog = resources.McpIntegrationDialog;
|
|
92
144
|
const [view, setView] = useState<View>("menu");
|
|
93
145
|
const skillFileInputRef = useRef<HTMLInputElement>(null);
|
|
94
|
-
const skillControls = useRef<ComposerContextPageControls | null>(null);
|
|
95
|
-
const skillFilePickerOpen = useRef(false);
|
|
96
|
-
const skillPageDismissedWhilePickerOpen = useRef(false);
|
|
97
|
-
const skillResumeTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
98
146
|
const skillEpoch = useRef(0);
|
|
99
147
|
const skillRequest = useRef<AbortController | null>(null);
|
|
100
148
|
const skillCloseTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
@@ -114,48 +162,24 @@ export function useComposerDefaultActions({
|
|
|
114
162
|
if (skillCloseTimer.current !== null) clearTimeout(skillCloseTimer.current);
|
|
115
163
|
skillCloseTimer.current = null;
|
|
116
164
|
}, []);
|
|
117
|
-
const cancelSkillWork =
|
|
118
|
-
skillFilePickerOpen.current = false;
|
|
119
|
-
skillPageDismissedWhilePickerOpen.current = false;
|
|
120
|
-
if (skillResumeTimer.current !== null)
|
|
121
|
-
clearTimeout(skillResumeTimer.current);
|
|
122
|
-
skillResumeTimer.current = null;
|
|
123
|
-
invalidateSkillWork();
|
|
124
|
-
}, [invalidateSkillWork]);
|
|
125
|
-
const finishSkillFilePicker = useCallback(() => {
|
|
126
|
-
skillFilePickerOpen.current = false;
|
|
127
|
-
if (!skillPageDismissedWhilePickerOpen.current) return;
|
|
128
|
-
skillPageDismissedWhilePickerOpen.current = false;
|
|
129
|
-
if (skillResumeTimer.current !== null)
|
|
130
|
-
clearTimeout(skillResumeTimer.current);
|
|
131
|
-
skillResumeTimer.current = setTimeout(() => {
|
|
132
|
-
skillResumeTimer.current = null;
|
|
133
|
-
skillControls.current?.onResume();
|
|
134
|
-
}, 0);
|
|
135
|
-
}, []);
|
|
136
|
-
const dismissSkillPage = useCallback(() => {
|
|
137
|
-
if (skillFilePickerOpen.current) {
|
|
138
|
-
skillPageDismissedWhilePickerOpen.current = true;
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
cancelSkillWork();
|
|
142
|
-
}, [cancelSkillWork]);
|
|
143
|
-
useEffect(() => {
|
|
144
|
-
const input = skillFileInputRef.current;
|
|
145
|
-
input?.addEventListener("cancel", finishSkillFilePicker);
|
|
146
|
-
return () => {
|
|
147
|
-
input?.removeEventListener("cancel", finishSkillFilePicker);
|
|
148
|
-
if (skillResumeTimer.current !== null)
|
|
149
|
-
clearTimeout(skillResumeTimer.current);
|
|
150
|
-
};
|
|
151
|
-
}, [finishSkillFilePicker]);
|
|
165
|
+
const cancelSkillWork = invalidateSkillWork;
|
|
152
166
|
useEffect(() => cancelSkillWork, [cancelSkillWork, adapters.resolvePath]);
|
|
153
167
|
useEffect(() => {
|
|
154
168
|
if (!disabled) return;
|
|
155
169
|
cancelSkillWork();
|
|
170
|
+
setView("menu");
|
|
156
171
|
setMcpDialogOpen(false);
|
|
157
|
-
overlayOpen.current = false;
|
|
158
172
|
}, [disabled, cancelSkillWork]);
|
|
173
|
+
useEffect(() => {
|
|
174
|
+
setView("menu");
|
|
175
|
+
return cancelSkillWork;
|
|
176
|
+
}, [integrationStatus?.scopeKey, cancelSkillWork]);
|
|
177
|
+
useEffect(() => {
|
|
178
|
+
const input = skillFileInputRef.current;
|
|
179
|
+
const restore = () => onRestoreFocus?.();
|
|
180
|
+
input?.addEventListener("cancel", restore);
|
|
181
|
+
return () => input?.removeEventListener("cancel", restore);
|
|
182
|
+
}, [onRestoreFocus]);
|
|
159
183
|
const resetSkillUpload = () => {
|
|
160
184
|
cancelSkillWork();
|
|
161
185
|
setView("menu");
|
|
@@ -169,6 +193,8 @@ export function useComposerDefaultActions({
|
|
|
169
193
|
invalidateSkillWork();
|
|
170
194
|
const epoch = skillEpoch.current;
|
|
171
195
|
setSkillUploadStatus(null);
|
|
196
|
+
setSkillUploadFileName(file.name);
|
|
197
|
+
setView("skill-upload");
|
|
172
198
|
try {
|
|
173
199
|
const content = await file.text();
|
|
174
200
|
if (skillEpoch.current !== epoch) return;
|
|
@@ -238,7 +264,7 @@ export function useComposerDefaultActions({
|
|
|
238
264
|
}),
|
|
239
265
|
});
|
|
240
266
|
skillCloseTimer.current = setTimeout(() => {
|
|
241
|
-
if (skillEpoch.current === epoch)
|
|
267
|
+
if (skillEpoch.current === epoch) resetSkillUpload();
|
|
242
268
|
}, 1200);
|
|
243
269
|
} catch (error) {
|
|
244
270
|
if (skillEpoch.current !== epoch) return;
|
|
@@ -262,6 +288,9 @@ export function useComposerDefaultActions({
|
|
|
262
288
|
const items: ComposerContextMenuItem[] = [
|
|
263
289
|
{
|
|
264
290
|
id: "schedule-task",
|
|
291
|
+
section: "commands" as const,
|
|
292
|
+
order: 10,
|
|
293
|
+
icon: <IconCalendarTime />,
|
|
265
294
|
label: t("agentChat.composer.menu.scheduleTask", {
|
|
266
295
|
defaultValue: "Schedule Task",
|
|
267
296
|
}),
|
|
@@ -275,6 +304,9 @@ export function useComposerDefaultActions({
|
|
|
275
304
|
},
|
|
276
305
|
{
|
|
277
306
|
id: "create-automation",
|
|
307
|
+
section: "commands" as const,
|
|
308
|
+
order: 20,
|
|
309
|
+
icon: <IconBolt />,
|
|
278
310
|
label: t("agentChat.composer.menu.createAutomation", {
|
|
279
311
|
defaultValue: "Create Automation",
|
|
280
312
|
}),
|
|
@@ -290,6 +322,9 @@ export function useComposerDefaultActions({
|
|
|
290
322
|
? [
|
|
291
323
|
{
|
|
292
324
|
id: "create-extension",
|
|
325
|
+
section: "commands" as const,
|
|
326
|
+
order: 40,
|
|
327
|
+
icon: <IconCode />,
|
|
293
328
|
label: t("agentChat.composer.menu.createExtension", {
|
|
294
329
|
defaultValue: "Create Extension",
|
|
295
330
|
}),
|
|
@@ -307,6 +342,10 @@ export function useComposerDefaultActions({
|
|
|
307
342
|
? [
|
|
308
343
|
{
|
|
309
344
|
id: "integrations",
|
|
345
|
+
opensDialog: true,
|
|
346
|
+
section: "integrations" as const,
|
|
347
|
+
order: 50,
|
|
348
|
+
icon: <IconPlugConnected />,
|
|
310
349
|
label: t("agentChat.composer.menu.integrations", {
|
|
311
350
|
defaultValue: "Integrations",
|
|
312
351
|
}),
|
|
@@ -316,7 +355,6 @@ export function useComposerDefaultActions({
|
|
|
316
355
|
}),
|
|
317
356
|
],
|
|
318
357
|
onSelect: () => {
|
|
319
|
-
overlayOpen.current = true;
|
|
320
358
|
setMcpDialogOpen(true);
|
|
321
359
|
},
|
|
322
360
|
},
|
|
@@ -324,6 +362,9 @@ export function useComposerDefaultActions({
|
|
|
324
362
|
: []),
|
|
325
363
|
{
|
|
326
364
|
id: "create-skill",
|
|
365
|
+
section: "commands" as const,
|
|
366
|
+
order: 30,
|
|
367
|
+
icon: <IconSchool />,
|
|
327
368
|
label: t("agentChat.composer.menu.createSkill", {
|
|
328
369
|
defaultValue: "Create Skill",
|
|
329
370
|
}),
|
|
@@ -335,155 +376,28 @@ export function useComposerDefaultActions({
|
|
|
335
376
|
defaultValue: "Upload skill file",
|
|
336
377
|
}),
|
|
337
378
|
],
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
})}
|
|
354
|
-
</DropdownMenuItem>
|
|
355
|
-
<DropdownMenuItem
|
|
356
|
-
onSelect={(event) => {
|
|
357
|
-
event.preventDefault();
|
|
358
|
-
const input = skillFileInputRef.current;
|
|
359
|
-
if (!input) return;
|
|
360
|
-
skillPageDismissedWhilePickerOpen.current = false;
|
|
361
|
-
skillFilePickerOpen.current = true;
|
|
362
|
-
controls.onClose({ restoreFocus: false });
|
|
363
|
-
input.click();
|
|
364
|
-
}}
|
|
365
|
-
>
|
|
366
|
-
{t("agentChat.composer.skill.uploadFile", {
|
|
367
|
-
defaultValue: "Upload skill file",
|
|
368
|
-
})}
|
|
369
|
-
</DropdownMenuItem>
|
|
370
|
-
{skillUploadStatus && (
|
|
371
|
-
<div role="alert" className="p-3 text-sm text-destructive">
|
|
372
|
-
{skillUploadStatus.message}
|
|
373
|
-
</div>
|
|
374
|
-
)}
|
|
375
|
-
</DropdownMenuGroup>
|
|
376
|
-
) : (
|
|
377
|
-
<form
|
|
378
|
-
className="grid min-w-0 gap-2 p-3"
|
|
379
|
-
onSubmit={(event) => {
|
|
380
|
-
event.preventDefault();
|
|
381
|
-
event.stopPropagation();
|
|
382
|
-
void submitSkillUpload();
|
|
383
|
-
}}
|
|
384
|
-
onKeyDown={(event) => {
|
|
385
|
-
if (event.key !== "Escape" && event.key !== "Tab")
|
|
386
|
-
event.stopPropagation();
|
|
387
|
-
}}
|
|
388
|
-
>
|
|
389
|
-
<Button
|
|
390
|
-
type="button"
|
|
391
|
-
variant="ghost"
|
|
392
|
-
size="sm"
|
|
393
|
-
className="-ms-3 justify-self-start"
|
|
394
|
-
onClick={resetSkillUpload}
|
|
395
|
-
>
|
|
396
|
-
{t("agentChat.composer.skill.back", { defaultValue: "Back" })}
|
|
397
|
-
</Button>
|
|
398
|
-
<p className="break-words text-xs text-muted-foreground">
|
|
399
|
-
{t("agentChat.composer.skill.review", {
|
|
400
|
-
name:
|
|
401
|
-
skillUploadFileName ||
|
|
402
|
-
t("agentChat.composer.skill.selectedFile", {
|
|
403
|
-
defaultValue: "the selected file",
|
|
404
|
-
}),
|
|
405
|
-
defaultValue: `Review the content from ${skillUploadFileName || "the selected file"} before saving.`,
|
|
406
|
-
})}
|
|
407
|
-
</p>
|
|
408
|
-
<Label htmlFor={`${formId}-name`}>
|
|
409
|
-
{t("agentChat.composer.skill.name", {
|
|
410
|
-
defaultValue: "Skill name",
|
|
411
|
-
})}
|
|
412
|
-
</Label>
|
|
413
|
-
<Input
|
|
414
|
-
id={`${formId}-name`}
|
|
415
|
-
autoFocus
|
|
416
|
-
value={skillUploadSlug}
|
|
417
|
-
disabled={skillUploadBusy}
|
|
418
|
-
onChange={(event) => setSkillUploadSlug(event.target.value)}
|
|
419
|
-
placeholder="my-skill"
|
|
420
|
-
/>
|
|
421
|
-
<p className="break-words text-xs text-muted-foreground">
|
|
422
|
-
{t("agentChat.composer.skill.savedAt", {
|
|
423
|
-
defaultValue: "Saved at",
|
|
424
|
-
})}{" "}
|
|
425
|
-
<span className="font-mono">
|
|
426
|
-
skills/{slugifyName(skillUploadSlug || "uploaded-skill")}
|
|
427
|
-
/SKILL.md
|
|
428
|
-
</span>
|
|
429
|
-
</p>
|
|
430
|
-
<Label htmlFor={`${formId}-content`}>
|
|
431
|
-
{t("agentChat.composer.skill.content", {
|
|
432
|
-
defaultValue: "Content",
|
|
433
|
-
})}
|
|
434
|
-
</Label>
|
|
435
|
-
<Textarea
|
|
436
|
-
id={`${formId}-content`}
|
|
437
|
-
value={skillUploadContent}
|
|
438
|
-
disabled={skillUploadBusy}
|
|
439
|
-
onChange={(event) => setSkillUploadContent(event.target.value)}
|
|
440
|
-
rows={10}
|
|
441
|
-
className="font-mono text-xs"
|
|
442
|
-
/>
|
|
443
|
-
{skillUploadStatus && (
|
|
444
|
-
<div
|
|
445
|
-
role={skillUploadStatus.kind === "err" ? "alert" : "status"}
|
|
446
|
-
className={cn(
|
|
447
|
-
"break-words text-xs",
|
|
448
|
-
skillUploadStatus.kind === "err"
|
|
449
|
-
? "text-destructive"
|
|
450
|
-
: "text-muted-foreground",
|
|
451
|
-
)}
|
|
452
|
-
>
|
|
453
|
-
{skillUploadStatus.message}
|
|
454
|
-
</div>
|
|
455
|
-
)}
|
|
456
|
-
<div className="flex flex-wrap justify-end gap-2">
|
|
457
|
-
<Button type="button" variant="ghost" onClick={resetSkillUpload}>
|
|
458
|
-
{t("agentChat.common.cancel", { defaultValue: "Cancel" })}
|
|
459
|
-
</Button>
|
|
460
|
-
<Button
|
|
461
|
-
type="submit"
|
|
462
|
-
disabled={
|
|
463
|
-
skillUploadBusy ||
|
|
464
|
-
skillUploadStatus?.kind === "ok" ||
|
|
465
|
-
!skillUploadContent.trim() ||
|
|
466
|
-
!skillUploadSlug.trim()
|
|
467
|
-
}
|
|
468
|
-
>
|
|
469
|
-
{skillUploadBusy ? (
|
|
470
|
-
<IconLoader2 className="animate-spin" />
|
|
471
|
-
) : (
|
|
472
|
-
t("agentChat.common.save", { defaultValue: "Save" })
|
|
473
|
-
)}
|
|
474
|
-
</Button>
|
|
475
|
-
</div>
|
|
476
|
-
</form>
|
|
477
|
-
);
|
|
379
|
+
disabled: !onSelectMode,
|
|
380
|
+
onSelect: () => onSelectMode?.("skill"),
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
id: "upload-skill",
|
|
384
|
+
opensDialog: true,
|
|
385
|
+
section: "commands",
|
|
386
|
+
order: 35,
|
|
387
|
+
icon: <IconSchool />,
|
|
388
|
+
label: t("agentChat.composer.skill.uploadFile", {
|
|
389
|
+
defaultValue: "Upload skill file",
|
|
390
|
+
}),
|
|
391
|
+
onSelect: () => {
|
|
392
|
+
resetSkillUpload();
|
|
393
|
+
skillFileInputRef.current?.click();
|
|
478
394
|
},
|
|
479
395
|
},
|
|
480
396
|
];
|
|
481
397
|
|
|
482
398
|
return {
|
|
483
399
|
items,
|
|
484
|
-
restoreFocus:
|
|
485
|
-
if (!overlayOpen.current) onRestoreFocus?.();
|
|
486
|
-
},
|
|
400
|
+
restoreFocus: onRestoreFocus,
|
|
487
401
|
overlays: (
|
|
488
402
|
<>
|
|
489
403
|
<input
|
|
@@ -494,15 +408,133 @@ export function useComposerDefaultActions({
|
|
|
494
408
|
onChange={(event) => {
|
|
495
409
|
const file = event.target.files?.[0];
|
|
496
410
|
event.target.value = "";
|
|
497
|
-
finishSkillFilePicker();
|
|
498
411
|
if (file) void handleSkillFileSelected(file);
|
|
499
412
|
}}
|
|
500
413
|
/>
|
|
414
|
+
<Dialog
|
|
415
|
+
open={view === "skill-upload"}
|
|
416
|
+
onOpenChange={(open) => {
|
|
417
|
+
if (!open) resetSkillUpload();
|
|
418
|
+
}}
|
|
419
|
+
>
|
|
420
|
+
<DialogContent
|
|
421
|
+
aria-describedby={undefined}
|
|
422
|
+
closeLabel={t("agentChat.common.close", { defaultValue: "Close" })}
|
|
423
|
+
onCloseAutoFocus={(event) => {
|
|
424
|
+
if (onRestoreFocus) {
|
|
425
|
+
event.preventDefault();
|
|
426
|
+
onRestoreFocus();
|
|
427
|
+
}
|
|
428
|
+
}}
|
|
429
|
+
>
|
|
430
|
+
<DialogHeader>
|
|
431
|
+
<DialogTitle>
|
|
432
|
+
{t("agentChat.composer.skill.uploadFile", {
|
|
433
|
+
defaultValue: "Upload skill file",
|
|
434
|
+
})}
|
|
435
|
+
</DialogTitle>
|
|
436
|
+
</DialogHeader>
|
|
437
|
+
<form
|
|
438
|
+
className="grid min-w-0 gap-2 p-3"
|
|
439
|
+
onSubmit={(event) => {
|
|
440
|
+
event.preventDefault();
|
|
441
|
+
event.stopPropagation();
|
|
442
|
+
void submitSkillUpload();
|
|
443
|
+
}}
|
|
444
|
+
onKeyDown={(event) => {
|
|
445
|
+
if (event.key !== "Escape" && event.key !== "Tab")
|
|
446
|
+
event.stopPropagation();
|
|
447
|
+
}}
|
|
448
|
+
>
|
|
449
|
+
<p className="break-words text-xs text-muted-foreground">
|
|
450
|
+
{t("agentChat.composer.skill.review", {
|
|
451
|
+
name:
|
|
452
|
+
skillUploadFileName ||
|
|
453
|
+
t("agentChat.composer.skill.selectedFile", {
|
|
454
|
+
defaultValue: "the selected file",
|
|
455
|
+
}),
|
|
456
|
+
defaultValue: `Review the content from ${skillUploadFileName || "the selected file"} before saving.`,
|
|
457
|
+
})}
|
|
458
|
+
</p>
|
|
459
|
+
<Label htmlFor={`${formId}-name`}>
|
|
460
|
+
{t("agentChat.composer.skill.name", {
|
|
461
|
+
defaultValue: "Skill name",
|
|
462
|
+
})}
|
|
463
|
+
</Label>
|
|
464
|
+
<Input
|
|
465
|
+
id={`${formId}-name`}
|
|
466
|
+
autoFocus
|
|
467
|
+
value={skillUploadSlug}
|
|
468
|
+
disabled={skillUploadBusy}
|
|
469
|
+
onChange={(event) => setSkillUploadSlug(event.target.value)}
|
|
470
|
+
placeholder="my-skill"
|
|
471
|
+
/>
|
|
472
|
+
<p className="break-words text-xs text-muted-foreground">
|
|
473
|
+
{t("agentChat.composer.skill.savedAt", {
|
|
474
|
+
defaultValue: "Saved at",
|
|
475
|
+
})}{" "}
|
|
476
|
+
<span className="font-mono">
|
|
477
|
+
skills/{slugifyName(skillUploadSlug || "uploaded-skill")}
|
|
478
|
+
/SKILL.md
|
|
479
|
+
</span>
|
|
480
|
+
</p>
|
|
481
|
+
<Label htmlFor={`${formId}-content`}>
|
|
482
|
+
{t("agentChat.composer.skill.content", {
|
|
483
|
+
defaultValue: "Content",
|
|
484
|
+
})}
|
|
485
|
+
</Label>
|
|
486
|
+
<Textarea
|
|
487
|
+
id={`${formId}-content`}
|
|
488
|
+
value={skillUploadContent}
|
|
489
|
+
disabled={skillUploadBusy}
|
|
490
|
+
onChange={(event) => setSkillUploadContent(event.target.value)}
|
|
491
|
+
rows={10}
|
|
492
|
+
className="font-mono text-xs"
|
|
493
|
+
/>
|
|
494
|
+
{skillUploadStatus && (
|
|
495
|
+
<div
|
|
496
|
+
role={skillUploadStatus.kind === "err" ? "alert" : "status"}
|
|
497
|
+
className={cn(
|
|
498
|
+
"break-words text-xs",
|
|
499
|
+
skillUploadStatus.kind === "err"
|
|
500
|
+
? "text-destructive"
|
|
501
|
+
: "text-muted-foreground",
|
|
502
|
+
)}
|
|
503
|
+
>
|
|
504
|
+
{skillUploadStatus.message}
|
|
505
|
+
</div>
|
|
506
|
+
)}
|
|
507
|
+
<div className="flex flex-wrap justify-end gap-2">
|
|
508
|
+
<Button
|
|
509
|
+
type="button"
|
|
510
|
+
variant="ghost"
|
|
511
|
+
onClick={resetSkillUpload}
|
|
512
|
+
>
|
|
513
|
+
{t("agentChat.common.cancel", { defaultValue: "Cancel" })}
|
|
514
|
+
</Button>
|
|
515
|
+
<Button
|
|
516
|
+
type="submit"
|
|
517
|
+
disabled={
|
|
518
|
+
skillUploadBusy ||
|
|
519
|
+
skillUploadStatus?.kind === "ok" ||
|
|
520
|
+
!skillUploadContent.trim() ||
|
|
521
|
+
!skillUploadSlug.trim()
|
|
522
|
+
}
|
|
523
|
+
>
|
|
524
|
+
{skillUploadBusy ? (
|
|
525
|
+
<IconLoader2 className="animate-spin" />
|
|
526
|
+
) : (
|
|
527
|
+
t("agentChat.common.save", { defaultValue: "Save" })
|
|
528
|
+
)}
|
|
529
|
+
</Button>
|
|
530
|
+
</div>
|
|
531
|
+
</form>
|
|
532
|
+
</DialogContent>
|
|
533
|
+
</Dialog>
|
|
501
534
|
{McpIntegrationDialog ? (
|
|
502
535
|
<McpIntegrationDialog
|
|
503
536
|
open={mcpDialogOpen}
|
|
504
537
|
onOpenChange={(open: boolean) => {
|
|
505
|
-
overlayOpen.current = open;
|
|
506
538
|
setMcpDialogOpen(open);
|
|
507
539
|
if (!open) onRestoreFocus?.();
|
|
508
540
|
}}
|
|
@@ -524,19 +556,11 @@ function ComposerFullContextMenu(props: ComposerPlusMenuProps) {
|
|
|
524
556
|
defaults.items,
|
|
525
557
|
props.contextMenuItems ?? [],
|
|
526
558
|
);
|
|
527
|
-
const defaultActionIds = new Set(defaults.items.map((item) => item.id));
|
|
528
|
-
const menuActionItems = mergedItems.filter((item) =>
|
|
529
|
-
defaultActionIds.has(item.id),
|
|
530
|
-
);
|
|
531
|
-
const contextItems = mergedItems.filter(
|
|
532
|
-
(item) => !defaultActionIds.has(item.id),
|
|
533
|
-
);
|
|
534
559
|
return (
|
|
535
560
|
<>
|
|
536
561
|
<ComposerContextMenu
|
|
537
562
|
{...props}
|
|
538
|
-
items={
|
|
539
|
-
menuActionItems={menuActionItems}
|
|
563
|
+
items={mergedItems}
|
|
540
564
|
addAttachment={
|
|
541
565
|
props.attachmentsEnabled === false
|
|
542
566
|
? undefined
|
|
@@ -556,24 +580,72 @@ export function ComposerPlusMenu({
|
|
|
556
580
|
contextMenuItems = [],
|
|
557
581
|
terminalModeControl,
|
|
558
582
|
attachmentsEnabled = true,
|
|
583
|
+
onSelectIntegration,
|
|
584
|
+
addAttachment,
|
|
585
|
+
onAttachmentRequest,
|
|
559
586
|
...props
|
|
560
587
|
}: ComposerPlusMenuProps) {
|
|
561
588
|
const runtime = useComposerRuntime();
|
|
562
|
-
const
|
|
589
|
+
const adapters = useComposerRuntimeAdapters();
|
|
590
|
+
const t = adapters.translate;
|
|
591
|
+
const workspace = adapters.resources?.useWorkspaceMenu?.({
|
|
592
|
+
enabled: props.open === true && mode !== "terminal",
|
|
593
|
+
...(props.onRestoreFocus ? { onRestoreFocus: props.onRestoreFocus } : {}),
|
|
594
|
+
onSelectIntegration: (reference) => {
|
|
595
|
+
if (!onSelectIntegration)
|
|
596
|
+
throw new Error(
|
|
597
|
+
t("agentChat.composer.contextActionFailed", {
|
|
598
|
+
defaultValue: "Could not add context.",
|
|
599
|
+
}),
|
|
600
|
+
);
|
|
601
|
+
onSelectIntegration(reference);
|
|
602
|
+
},
|
|
603
|
+
});
|
|
604
|
+
const scopeEntries = (
|
|
605
|
+
entries: readonly ComposerContextMenuItem[],
|
|
606
|
+
): ComposerContextMenuItem[] =>
|
|
607
|
+
entries.map((entry) => {
|
|
608
|
+
if (
|
|
609
|
+
entry.picker &&
|
|
610
|
+
entry.picker.identityScope === "workspace" &&
|
|
611
|
+
workspace?.scopeKey !== undefined
|
|
612
|
+
)
|
|
613
|
+
return {
|
|
614
|
+
...entry,
|
|
615
|
+
picker: { ...entry.picker, scopeKey: workspace.scopeKey },
|
|
616
|
+
};
|
|
617
|
+
return entry.children
|
|
618
|
+
? { ...entry, children: scopeEntries(entry.children) }
|
|
619
|
+
: entry;
|
|
620
|
+
});
|
|
621
|
+
contextMenuItems = scopeEntries(
|
|
622
|
+
mode === "terminal"
|
|
623
|
+
? contextMenuItems
|
|
624
|
+
: mergeComposerMenuItems(workspace?.items ?? [], contextMenuItems),
|
|
625
|
+
);
|
|
563
626
|
if (mode === "full") {
|
|
564
627
|
return (
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
628
|
+
<>
|
|
629
|
+
<ComposerFullContextMenu
|
|
630
|
+
{...props}
|
|
631
|
+
{...(workspace ? { integrationStatus: workspace } : {})}
|
|
632
|
+
{...(addAttachment ? { addAttachment } : {})}
|
|
633
|
+
{...(onAttachmentRequest ? { onAttachmentRequest } : {})}
|
|
634
|
+
attachmentsEnabled={attachmentsEnabled}
|
|
635
|
+
contextMenuItems={contextMenuItems}
|
|
636
|
+
/>
|
|
637
|
+
{workspace?.overlays}
|
|
638
|
+
</>
|
|
570
639
|
);
|
|
571
640
|
}
|
|
572
641
|
const terminalItems: ComposerContextMenuItem[] = terminalModeControl
|
|
573
642
|
? [
|
|
574
643
|
{
|
|
575
644
|
id: "terminal-primary",
|
|
576
|
-
|
|
645
|
+
order: 10,
|
|
646
|
+
label: t("agentPanel.newTerminal", {
|
|
647
|
+
defaultValue: "New terminal",
|
|
648
|
+
}),
|
|
577
649
|
disabled:
|
|
578
650
|
terminalModeControl.enabled && !terminalModeControl.onNewTerminal,
|
|
579
651
|
onSelect: () => {
|
|
@@ -584,6 +656,7 @@ export function ComposerPlusMenu({
|
|
|
584
656
|
},
|
|
585
657
|
{
|
|
586
658
|
id: "terminal-mode",
|
|
659
|
+
order: 20,
|
|
587
660
|
label: t("agentPanel.cliTerminalMode", {
|
|
588
661
|
defaultValue: "CLI terminal mode",
|
|
589
662
|
}),
|
|
@@ -599,22 +672,34 @@ export function ComposerPlusMenu({
|
|
|
599
672
|
: contextMenuItems;
|
|
600
673
|
const terminalActionIds = new Set(terminalItems.map((item) => item.id));
|
|
601
674
|
return (
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
(
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
675
|
+
<>
|
|
676
|
+
<ComposerContextMenu
|
|
677
|
+
{...props}
|
|
678
|
+
{...(mode !== "terminal" && workspace
|
|
679
|
+
? { integrationStatus: workspace }
|
|
680
|
+
: {})}
|
|
681
|
+
items={
|
|
682
|
+
mode === "terminal"
|
|
683
|
+
? mergedTerminalItems.filter(
|
|
684
|
+
(item) => !terminalActionIds.has(item.id),
|
|
685
|
+
)
|
|
686
|
+
: contextMenuItems
|
|
687
|
+
}
|
|
688
|
+
menuActionItems={
|
|
689
|
+
mode === "terminal"
|
|
690
|
+
? mergedTerminalItems.filter((item) =>
|
|
691
|
+
terminalActionIds.has(item.id),
|
|
692
|
+
)
|
|
693
|
+
: []
|
|
694
|
+
}
|
|
695
|
+
{...(mode === "upload-only" && attachmentsEnabled
|
|
696
|
+
? { addAttachment: addAttachment ?? runtime.addAttachment }
|
|
697
|
+
: {})}
|
|
698
|
+
{...(mode === "upload-only" && onAttachmentRequest
|
|
699
|
+
? { onAttachmentRequest }
|
|
700
|
+
: {})}
|
|
701
|
+
/>
|
|
702
|
+
{workspace?.overlays}
|
|
703
|
+
</>
|
|
619
704
|
);
|
|
620
705
|
}
|