@mcp-b/react-components 0.42.0 → 0.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AgentChat-DVr2giwD.d.ts → AgentChat-Bibfj7u1.d.ts} +1 -1
- package/dist/{AgentChatStartScreen-CO49yepa.d.ts → AgentChatStartScreen-Bkv7Avni.d.ts} +6 -0
- package/dist/McpPluginCatalog-mbGw8FTu.d.ts +92 -0
- package/dist/ResponsiveSidebarShell-DOXd5T-d.d.ts +111 -0
- package/dist/SetupChecklist-H1JRCIIe.js +77 -0
- package/dist/{ThinkChatActivity-CsDql-ER.d.ts → ThinkChatActivity-CgvmTXXB.d.ts} +1 -1
- package/dist/Workspace-F3raHdYV.d.ts +140 -0
- package/dist/{WorkspaceFileView-DwdXiKku.js → WorkspaceFileView-DWMKxX_u.js} +0 -1
- package/dist/components/agents-sdk/AgentChat.d.ts +1 -1
- package/dist/components/agents-sdk/ManagerOffice.js +1 -1
- package/dist/components/agents-sdk/McpPluginCatalog.d.ts +1 -91
- package/dist/components/agents-sdk/McpPluginCatalog.js +1 -1
- package/dist/components/agents-sdk/SubagentRunSelector.js +1 -1
- package/dist/components/agents-sdk/ThinkChat.d.ts +2 -2
- package/dist/components/agents-sdk/ThinkChat.js +1 -1
- package/dist/components/agents-sdk/ThinkChatActivity.d.ts +1 -1
- package/dist/components/agents-sdk/ThinkChatActivity.js +1 -1
- package/dist/components/agents-sdk/ThinkExecutionDetail.js +1 -1
- package/dist/components/agents-sdk/ThinkFullApp.d.ts +20 -6
- package/dist/components/agents-sdk/ThinkFullApp.js +6 -5
- package/dist/components/agents-sdk/ThinkFullAppViewSwitch.js +1 -1
- package/dist/components/agents-sdk/ThinkRoutineDetail.js +1 -1
- package/dist/components/agents-sdk/ThinkRoutineLibrary.d.ts +4 -3
- package/dist/components/agents-sdk/ThinkRoutineLibrary.js +17 -31
- package/dist/components/agents-sdk/ThinkSidepanel.d.ts +173 -0
- package/dist/components/agents-sdk/ThinkSidepanel.js +656 -0
- package/dist/components/agents-sdk/ThinkThreadPicker.d.ts +4 -5
- package/dist/components/agents-sdk/ThinkThreadPicker.js +6 -6
- package/dist/components/agents-sdk/Workspace.d.ts +1 -139
- package/dist/components/agents-sdk/WorkspaceBrowser.d.ts +1 -1
- package/dist/components/agents-sdk/WorkspaceExplorer.d.ts +1 -1
- package/dist/components/agents-sdk/WorkspaceExplorer.js +3 -3
- package/dist/components/agents-sdk/WorkspaceFileView.js +1 -1
- package/dist/components/ai-sdk/AgentChatStartScreen.d.ts +1 -1
- package/dist/components/ai-sdk/AgentChatStartScreen.js +5 -2
- package/dist/components/foundations/ToggleGroup.d.ts +1 -1
- package/dist/components/foundations/ToggleGroup.js +1 -1
- package/dist/components/general-purpose/PricingBillingToggle.js +1 -1
- package/dist/components/general-purpose/PricingUsageCalculator.js +1 -1
- package/dist/components/general-purpose/ResponsiveSidebarShell.d.ts +1 -104
- package/dist/components/general-purpose/ResponsiveSidebarShell.js +2 -2
- package/dist/components/general-purpose/SetupChecklist.js +1 -76
- package/dist/components/general-purpose/ThemeModeControl.js +1 -1
- package/dist/components/nanites/AgentToolDetail.js +3 -3
- package/dist/styles/agent-chat.css +20 -15
- package/dist/styles/index.css +1 -0
- package/dist/styles/responsive-sidebar-shell.css +12 -9
- package/dist/styles/think-sidepanel.css +74 -0
- package/package.json +2 -2
- package/dist/{ThinkChat-DkA4Wr71.js → ThinkChat-BES_3Mb-.js} +1 -1
|
@@ -0,0 +1,656 @@
|
|
|
1
|
+
import { t as cx } from "../../class-names-BiMDVpUo.js";
|
|
2
|
+
import { $ as WarningIcon, C as FolderIcon, G as SlackIcon, I as PaperclipIcon, K as SpinnerIcon, R as PencilIcon, S as FileIcon, T as InfoIcon, V as QueueIcon, Z as TerminalIcon, b as EyeIcon, c as BoxIcon, g as DiscordIcon, k as McpIcon, o as ArrowUpRightIcon, q as SquareIcon, r as ArrowLeftIcon, y as EllipsisIcon } from "../../icons-CVFSeTJn.js";
|
|
3
|
+
import { Button } from "../foundations/Button.js";
|
|
4
|
+
import { Tooltip } from "../foundations/Tooltip.js";
|
|
5
|
+
import { Menu } from "../foundations/Menu.js";
|
|
6
|
+
import { Dialog } from "../foundations/Dialog.js";
|
|
7
|
+
import { ChatGptSignInScreen } from "../extension/ChatGptSignInScreen.js";
|
|
8
|
+
import { Avatar } from "../foundations/Avatar.js";
|
|
9
|
+
import { EmptyState } from "../foundations/EmptyState.js";
|
|
10
|
+
import { AppIcon } from "../foundations/AppIcon.js";
|
|
11
|
+
import "../foundations/icons.js";
|
|
12
|
+
import { AppTopBar } from "../general-purpose/AppTopBar.js";
|
|
13
|
+
import { DescriptionList } from "../foundations/DescriptionList.js";
|
|
14
|
+
import { McpServerPickerAction, McpServerPickerItems } from "./McpServerPicker.js";
|
|
15
|
+
import { NaniteMark } from "../nanites/NaniteScene.js";
|
|
16
|
+
import { getThinkExecutionRunId } from "./ThinkExecutionRun.js";
|
|
17
|
+
import { ThinkThreadPicker, summarizeThinkThreads } from "./ThinkThreadPicker.js";
|
|
18
|
+
import { ThinkFullApp } from "./ThinkFullApp.js";
|
|
19
|
+
import { Switch } from "../foundations/Switch.js";
|
|
20
|
+
import { ThinkRoutineLibrary } from "./ThinkRoutineLibrary.js";
|
|
21
|
+
import { ActionGuide } from "../general-purpose/ActionGuide.js";
|
|
22
|
+
import { t as SetupChecklistAction } from "../../SetupChecklist-H1JRCIIe.js";
|
|
23
|
+
import { useTheme } from "../foundations/ThemeProvider.js";
|
|
24
|
+
import * as React from "react";
|
|
25
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
26
|
+
//#region src/components/agents-sdk/ThinkSidepanel.tsx
|
|
27
|
+
const EMPTY_THREADS = [];
|
|
28
|
+
function AppearanceMenu() {
|
|
29
|
+
const { preference, setPreference } = useTheme();
|
|
30
|
+
return /* @__PURE__ */ jsxs(Menu.RadioGroup, {
|
|
31
|
+
value: preference,
|
|
32
|
+
onValueChange: (value) => {
|
|
33
|
+
if (value === "light" || value === "dark" || value === "system") setPreference(value);
|
|
34
|
+
},
|
|
35
|
+
children: [
|
|
36
|
+
/* @__PURE__ */ jsxs(Menu.RadioItem, {
|
|
37
|
+
value: "light",
|
|
38
|
+
children: [/* @__PURE__ */ jsx(Menu.RadioItemIndicator, {}), "Light"]
|
|
39
|
+
}),
|
|
40
|
+
/* @__PURE__ */ jsxs(Menu.RadioItem, {
|
|
41
|
+
value: "dark",
|
|
42
|
+
children: [/* @__PURE__ */ jsx(Menu.RadioItemIndicator, {}), "Dark"]
|
|
43
|
+
}),
|
|
44
|
+
/* @__PURE__ */ jsxs(Menu.RadioItem, {
|
|
45
|
+
value: "system",
|
|
46
|
+
children: [/* @__PURE__ */ jsx(Menu.RadioItemIndicator, {}), "System"]
|
|
47
|
+
})
|
|
48
|
+
]
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
function MenuGroupLabel({ hint, label }) {
|
|
52
|
+
return /* @__PURE__ */ jsxs(Menu.GroupLabel, {
|
|
53
|
+
className: "think-sidepanel__menu-group-label",
|
|
54
|
+
children: [label, /* @__PURE__ */ jsxs(Tooltip.Root, { children: [/* @__PURE__ */ jsx(Tooltip.Trigger, {
|
|
55
|
+
render: /* @__PURE__ */ jsx("span", { className: "think-sidepanel__menu-hint" }),
|
|
56
|
+
children: /* @__PURE__ */ jsx(InfoIcon, {})
|
|
57
|
+
}), /* @__PURE__ */ jsx(Tooltip.Portal, { children: /* @__PURE__ */ jsx(Tooltip.Positioner, { children: /* @__PURE__ */ jsx(Tooltip.Popup, { children: hint }) }) })] })]
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
function OverflowMenu({ companion, follow, identityEmail, onIdentity, onModel, onSignOut, passkeyVault, renderLink }) {
|
|
61
|
+
return /* @__PURE__ */ jsxs(Menu.Root, { children: [/* @__PURE__ */ jsx(AppTopBar.Button, {
|
|
62
|
+
label: "More actions",
|
|
63
|
+
tooltip: identityEmail ? `Signed in as ${identityEmail}` : void 0,
|
|
64
|
+
render: /* @__PURE__ */ jsx(Menu.Trigger, {}),
|
|
65
|
+
children: identityEmail ? /* @__PURE__ */ jsx(Avatar.Root, {
|
|
66
|
+
size: "sm",
|
|
67
|
+
children: /* @__PURE__ */ jsx(Avatar.Fallback, { children: identityEmail[0]?.toUpperCase() })
|
|
68
|
+
}) : /* @__PURE__ */ jsx(EllipsisIcon, {})
|
|
69
|
+
}), /* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(Menu.Positioner, {
|
|
70
|
+
side: "bottom",
|
|
71
|
+
align: "end",
|
|
72
|
+
sideOffset: 4,
|
|
73
|
+
children: /* @__PURE__ */ jsxs(Menu.Popup, { children: [
|
|
74
|
+
/* @__PURE__ */ jsxs(Menu.Item, {
|
|
75
|
+
render: renderLink({
|
|
76
|
+
kind: "view",
|
|
77
|
+
view: "files"
|
|
78
|
+
}),
|
|
79
|
+
children: [/* @__PURE__ */ jsx(FileIcon, {}), "Files"]
|
|
80
|
+
}),
|
|
81
|
+
/* @__PURE__ */ jsxs(Menu.Item, {
|
|
82
|
+
render: renderLink({
|
|
83
|
+
kind: "view",
|
|
84
|
+
view: "plugins"
|
|
85
|
+
}),
|
|
86
|
+
children: [/* @__PURE__ */ jsx(BoxIcon, {}), "Plugins"]
|
|
87
|
+
}),
|
|
88
|
+
/* @__PURE__ */ jsxs(Menu.Item, {
|
|
89
|
+
render: renderLink({
|
|
90
|
+
kind: "view",
|
|
91
|
+
view: "schedules"
|
|
92
|
+
}),
|
|
93
|
+
children: [/* @__PURE__ */ jsx(QueueIcon, {}), "Routines"]
|
|
94
|
+
}),
|
|
95
|
+
follow ? /* @__PURE__ */ jsxs(Menu.CheckboxItem, {
|
|
96
|
+
checked: follow.followed,
|
|
97
|
+
onCheckedChange: follow.onCheckedChange,
|
|
98
|
+
children: [/* @__PURE__ */ jsx(EyeIcon, {}), "Follow this conversation"]
|
|
99
|
+
}) : null,
|
|
100
|
+
onIdentity ? /* @__PURE__ */ jsxs(Menu.Item, {
|
|
101
|
+
onClick: onIdentity,
|
|
102
|
+
children: [/* @__PURE__ */ jsx(InfoIcon, {}), "Identity"]
|
|
103
|
+
}) : null,
|
|
104
|
+
onModel ? /* @__PURE__ */ jsxs(Menu.Item, {
|
|
105
|
+
onClick: onModel,
|
|
106
|
+
children: [/* @__PURE__ */ jsx(TerminalIcon, {}), "Model"]
|
|
107
|
+
}) : null,
|
|
108
|
+
companion ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Menu.Separator, {}), /* @__PURE__ */ jsxs(Menu.Group, { children: [
|
|
109
|
+
/* @__PURE__ */ jsx(MenuGroupLabel, {
|
|
110
|
+
label: "Companion app",
|
|
111
|
+
hint: "Connecting lets this employee chat with the browser and watch it work from anywhere."
|
|
112
|
+
}),
|
|
113
|
+
/* @__PURE__ */ jsxs(Menu.CheckboxItem, {
|
|
114
|
+
className: "think-sidepanel__menu-switch-item",
|
|
115
|
+
checked: companion.enabled,
|
|
116
|
+
onCheckedChange: companion.setEnabled,
|
|
117
|
+
children: ["Connect this browser", /* @__PURE__ */ jsx(Switch.Root, {
|
|
118
|
+
"aria-hidden": true,
|
|
119
|
+
readOnly: true,
|
|
120
|
+
size: "sm",
|
|
121
|
+
checked: companion.enabled,
|
|
122
|
+
children: /* @__PURE__ */ jsx(Switch.Thumb, {})
|
|
123
|
+
})]
|
|
124
|
+
}),
|
|
125
|
+
/* @__PURE__ */ jsxs(Menu.Item, {
|
|
126
|
+
render: /* @__PURE__ */ jsx("a", {
|
|
127
|
+
href: companion.origin,
|
|
128
|
+
target: "_blank",
|
|
129
|
+
rel: "noreferrer",
|
|
130
|
+
"aria-label": companion.origin.replace(/^https?:\/\//, "")
|
|
131
|
+
}),
|
|
132
|
+
children: [/* @__PURE__ */ jsx(ArrowUpRightIcon, {}), companion.origin.replace(/^https?:\/\//, "")]
|
|
133
|
+
})
|
|
134
|
+
] })] }) : null,
|
|
135
|
+
passkeyVault ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Menu.Separator, {}), /* @__PURE__ */ jsxs(Menu.Group, { children: [/* @__PURE__ */ jsx(MenuGroupLabel, {
|
|
136
|
+
label: "Passkeys",
|
|
137
|
+
hint: "The employee saves and uses its own passkeys instead of the browser's."
|
|
138
|
+
}), /* @__PURE__ */ jsxs(Menu.CheckboxItem, {
|
|
139
|
+
className: "think-sidepanel__menu-switch-item",
|
|
140
|
+
checked: passkeyVault.enabled,
|
|
141
|
+
onCheckedChange: passkeyVault.setEnabled,
|
|
142
|
+
children: ["Use its own passkeys", /* @__PURE__ */ jsx(Switch.Root, {
|
|
143
|
+
"aria-hidden": true,
|
|
144
|
+
readOnly: true,
|
|
145
|
+
size: "sm",
|
|
146
|
+
checked: passkeyVault.enabled,
|
|
147
|
+
children: /* @__PURE__ */ jsx(Switch.Thumb, {})
|
|
148
|
+
})]
|
|
149
|
+
})] })] }) : null,
|
|
150
|
+
/* @__PURE__ */ jsx(Menu.Separator, {}),
|
|
151
|
+
/* @__PURE__ */ jsxs(Menu.Group, { children: [/* @__PURE__ */ jsx(Menu.GroupLabel, { children: "Appearance" }), /* @__PURE__ */ jsx(AppearanceMenu, {})] }),
|
|
152
|
+
onSignOut ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Menu.Separator, {}), /* @__PURE__ */ jsxs(Menu.Item, {
|
|
153
|
+
onClick: onSignOut,
|
|
154
|
+
children: [/* @__PURE__ */ jsx(ArrowUpRightIcon, {}), "Sign out"]
|
|
155
|
+
})] }) : null
|
|
156
|
+
] })
|
|
157
|
+
}) })] });
|
|
158
|
+
}
|
|
159
|
+
function GateScreen({ brand, connectingLabel, identity, modelSetup, status }) {
|
|
160
|
+
if (status === "connecting") return /* @__PURE__ */ jsx("div", {
|
|
161
|
+
className: "think-sidepanel__gate",
|
|
162
|
+
role: "status",
|
|
163
|
+
children: /* @__PURE__ */ jsx(EmptyState, {
|
|
164
|
+
icon: /* @__PURE__ */ jsx(SpinnerIcon, {}),
|
|
165
|
+
description: connectingLabel ?? "Connecting…"
|
|
166
|
+
})
|
|
167
|
+
});
|
|
168
|
+
if (status === "offline") return /* @__PURE__ */ jsx("main", {
|
|
169
|
+
className: "think-sidepanel__gate",
|
|
170
|
+
role: "status",
|
|
171
|
+
children: /* @__PURE__ */ jsx(EmptyState, {
|
|
172
|
+
icon: /* @__PURE__ */ jsx(WarningIcon, {}),
|
|
173
|
+
title: `${brand.name} is offline`,
|
|
174
|
+
description: "Open the browser and turn the companion connection on. This screen reconnects on its own."
|
|
175
|
+
})
|
|
176
|
+
});
|
|
177
|
+
if (status === "identity-blocked" && identity) return /* @__PURE__ */ jsxs("div", {
|
|
178
|
+
className: "think-sidepanel__gate",
|
|
179
|
+
role: "alert",
|
|
180
|
+
children: [/* @__PURE__ */ jsx(EmptyState, {
|
|
181
|
+
icon: /* @__PURE__ */ jsx(WarningIcon, {}),
|
|
182
|
+
title: "Wrong browser profile",
|
|
183
|
+
description: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("p", { children: [
|
|
184
|
+
"This installation is assigned to ",
|
|
185
|
+
/* @__PURE__ */ jsx("strong", { children: identity.assignedAccount }),
|
|
186
|
+
", but the live profile is ",
|
|
187
|
+
/* @__PURE__ */ jsx("strong", { children: identity.liveProfile }),
|
|
188
|
+
"."
|
|
189
|
+
] }), /* @__PURE__ */ jsx("p", { children: identity.managed ? "Open the assigned profile. Organization policy controls this assignment." : "Open the assigned profile, or remove the binding." })] })
|
|
190
|
+
}), identity.managed || !identity.onUnbind ? null : /* @__PURE__ */ jsx(Button, {
|
|
191
|
+
type: "button",
|
|
192
|
+
variant: "ghost",
|
|
193
|
+
color: "destructive",
|
|
194
|
+
onClick: identity.onUnbind,
|
|
195
|
+
children: "Remove binding"
|
|
196
|
+
})]
|
|
197
|
+
});
|
|
198
|
+
if (status === "needs-model") return /* @__PURE__ */ jsx(ChatGptSignInScreen, {
|
|
199
|
+
busy: modelSetup?.busy,
|
|
200
|
+
error: modelSetup?.error,
|
|
201
|
+
label: modelSetup?.label,
|
|
202
|
+
title: `Meet ${brand.name}`,
|
|
203
|
+
brandName: "SigVelo",
|
|
204
|
+
brandLogo: brand.logo,
|
|
205
|
+
onSignIn: modelSetup?.onSignIn,
|
|
206
|
+
secondaryAction: modelSetup?.onCustomEndpoint ? {
|
|
207
|
+
label: "Set up a custom model endpoint",
|
|
208
|
+
onSelect: modelSetup.onCustomEndpoint
|
|
209
|
+
} : void 0
|
|
210
|
+
});
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
function IdentityDialog({ identity, onOpenChange, open }) {
|
|
214
|
+
return /* @__PURE__ */ jsx(Dialog.Root, {
|
|
215
|
+
open,
|
|
216
|
+
onOpenChange,
|
|
217
|
+
children: /* @__PURE__ */ jsxs(Dialog.Portal, { children: [/* @__PURE__ */ jsx(Dialog.Backdrop, {}), /* @__PURE__ */ jsx(Dialog.Viewport, { children: /* @__PURE__ */ jsxs(Dialog.Popup, { children: [
|
|
218
|
+
/* @__PURE__ */ jsxs(Dialog.Header, { children: [/* @__PURE__ */ jsx(Dialog.Title, { children: "Operating identity" }), /* @__PURE__ */ jsx(Dialog.Description, { children: "This employee operates the live browser profile as its own identity. Assigning the account keeps it from signing in with another profile." })] }),
|
|
219
|
+
/* @__PURE__ */ jsxs(DescriptionList.Root, {
|
|
220
|
+
variant: "divided",
|
|
221
|
+
children: [/* @__PURE__ */ jsxs(DescriptionList.Item, { children: [/* @__PURE__ */ jsx(DescriptionList.Term, { children: "Live profile" }), /* @__PURE__ */ jsx(DescriptionList.Details, { children: identity.liveProfile })] }), /* @__PURE__ */ jsxs(DescriptionList.Item, { children: [/* @__PURE__ */ jsx(DescriptionList.Term, { children: "Assigned account" }), /* @__PURE__ */ jsx(DescriptionList.Details, { children: identity.managed ? `${identity.assignedAccount} (managed by your organization)` : identity.assignedAccount })] })]
|
|
222
|
+
}),
|
|
223
|
+
/* @__PURE__ */ jsx(Dialog.Footer, { children: identity.managed ? /* @__PURE__ */ jsx("p", { children: "Organization policy controls this binding." }) : identity.onUnbind && identity.assignedAccount ? /* @__PURE__ */ jsx(Button, {
|
|
224
|
+
type: "button",
|
|
225
|
+
variant: "ghost",
|
|
226
|
+
color: "destructive",
|
|
227
|
+
onClick: () => {
|
|
228
|
+
Promise.resolve(identity.onUnbind?.()).then(() => onOpenChange(false));
|
|
229
|
+
},
|
|
230
|
+
children: "Remove binding"
|
|
231
|
+
}) : /* @__PURE__ */ jsx(Button, {
|
|
232
|
+
type: "button",
|
|
233
|
+
color: "primary",
|
|
234
|
+
disabled: !identity.canBind || !identity.onBind,
|
|
235
|
+
onClick: () => {
|
|
236
|
+
Promise.resolve(identity.onBind?.()).then(() => onOpenChange(false));
|
|
237
|
+
},
|
|
238
|
+
children: "Assign this profile"
|
|
239
|
+
}) })
|
|
240
|
+
] }) })] })
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
function CapabilityGuide({ brandName, start }) {
|
|
244
|
+
const send = (text) => void start.onSubmit({
|
|
245
|
+
text,
|
|
246
|
+
files: []
|
|
247
|
+
});
|
|
248
|
+
return /* @__PURE__ */ jsx(ActionGuide, {
|
|
249
|
+
title: `${brandName} can work across your browser.`,
|
|
250
|
+
description: "They can act in signed-in tabs, keep workspace files, connect plugins, and run recurring work after this panel closes.",
|
|
251
|
+
sections: [
|
|
252
|
+
{
|
|
253
|
+
id: "quick-browser-job",
|
|
254
|
+
title: "Start with a quick browser job",
|
|
255
|
+
layout: "compact",
|
|
256
|
+
actions: [{
|
|
257
|
+
id: "organize-tabs",
|
|
258
|
+
icon: /* @__PURE__ */ jsx(BoxIcon, {}),
|
|
259
|
+
label: "Organize this window’s tabs by task"
|
|
260
|
+
}, {
|
|
261
|
+
id: "close-duplicate-tabs",
|
|
262
|
+
icon: /* @__PURE__ */ jsx(EyeIcon, {}),
|
|
263
|
+
label: "Close duplicate tabs in this window"
|
|
264
|
+
}]
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
id: "ongoing-work",
|
|
268
|
+
title: "Set up ongoing work",
|
|
269
|
+
layout: "cards",
|
|
270
|
+
actions: [
|
|
271
|
+
{
|
|
272
|
+
id: "create-routine",
|
|
273
|
+
icon: /* @__PURE__ */ jsx(QueueIcon, {}),
|
|
274
|
+
label: "Create a recurring task"
|
|
275
|
+
},
|
|
276
|
+
...start.slack && !start.slack.configured ? [{
|
|
277
|
+
id: "connect-slack",
|
|
278
|
+
icon: /* @__PURE__ */ jsx(SlackIcon, {}),
|
|
279
|
+
label: "Connect Slack"
|
|
280
|
+
}] : [],
|
|
281
|
+
...start.discord && !start.discord.configured ? [{
|
|
282
|
+
id: "connect-discord",
|
|
283
|
+
icon: /* @__PURE__ */ jsx(DiscordIcon, {}),
|
|
284
|
+
label: "Connect Discord"
|
|
285
|
+
}] : [],
|
|
286
|
+
...start.onAttachFolder ? [{
|
|
287
|
+
id: "attach-local-folder",
|
|
288
|
+
icon: /* @__PURE__ */ jsx(FolderIcon, {}),
|
|
289
|
+
label: "Attach a local folder"
|
|
290
|
+
}] : [],
|
|
291
|
+
{
|
|
292
|
+
id: "connections",
|
|
293
|
+
icon: /* @__PURE__ */ jsx(McpIcon, {}),
|
|
294
|
+
label: start.hasConnectedApps ? "Use my connected apps" : "Connect another app"
|
|
295
|
+
}
|
|
296
|
+
]
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
id: "larger-workflow",
|
|
300
|
+
title: "Build a larger workflow",
|
|
301
|
+
layout: "list",
|
|
302
|
+
actions: [
|
|
303
|
+
{
|
|
304
|
+
id: "automate-browser",
|
|
305
|
+
icon: /* @__PURE__ */ jsx(TerminalIcon, {}),
|
|
306
|
+
label: "Automate work across signed-in tabs",
|
|
307
|
+
variant: "ghost"
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
id: "move-workspace-files",
|
|
311
|
+
icon: /* @__PURE__ */ jsx(FolderIcon, {}),
|
|
312
|
+
label: "Move files between a website and the workspace",
|
|
313
|
+
variant: "ghost"
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
id: "record-browser-workflow",
|
|
317
|
+
icon: /* @__PURE__ */ jsx(EyeIcon, {}),
|
|
318
|
+
label: "Record a browser workflow as an MP4",
|
|
319
|
+
variant: "ghost"
|
|
320
|
+
}
|
|
321
|
+
]
|
|
322
|
+
}
|
|
323
|
+
],
|
|
324
|
+
onAction: (action) => {
|
|
325
|
+
switch (action.id) {
|
|
326
|
+
case "organize-tabs": return send("Organize this window’s tabs by task.");
|
|
327
|
+
case "close-duplicate-tabs": return send("Close duplicate tabs in this window.");
|
|
328
|
+
case "create-routine": return send("Help me create a recurring task that runs on a schedule.");
|
|
329
|
+
case "connect-slack": return start.slack?.onSelect();
|
|
330
|
+
case "connect-discord": return start.discord?.onSelect();
|
|
331
|
+
case "connections": return send(start.hasConnectedApps ? "Show me useful work I can do across my connected apps." : "Help me connect another app I use.");
|
|
332
|
+
case "automate-browser": return send("Automate a workflow across my signed-in browser tabs.");
|
|
333
|
+
case "move-workspace-files": return send("Move files between a signed-in website and the workspace.");
|
|
334
|
+
case "record-browser-workflow": return send("Record a browser workflow as an MP4.");
|
|
335
|
+
case "attach-local-folder": return start.onAttachFolder?.();
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
function StartComposerTray({ plugins, renderLink, start }) {
|
|
341
|
+
const hasPluginMenu = Boolean(plugins || start.slack || start.discord);
|
|
342
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
343
|
+
start.personalization ? /* @__PURE__ */ jsx(SetupChecklistAction, {
|
|
344
|
+
actionLabel: "Prompts",
|
|
345
|
+
label: "Prompts",
|
|
346
|
+
entries: start.personalization.entries,
|
|
347
|
+
onSelect: start.personalization.onSelect
|
|
348
|
+
}) : null,
|
|
349
|
+
start.onAttachFolder ? /* @__PURE__ */ jsxs(Button, {
|
|
350
|
+
type: "button",
|
|
351
|
+
variant: "ghost",
|
|
352
|
+
color: "neutral",
|
|
353
|
+
size: "md",
|
|
354
|
+
disabled: start.attachFolderBusy,
|
|
355
|
+
onClick: start.onAttachFolder,
|
|
356
|
+
"aria-label": "Connect a local folder",
|
|
357
|
+
children: [/* @__PURE__ */ jsx(PaperclipIcon, {}), /* @__PURE__ */ jsx("span", { children: "Connect a local folder" })]
|
|
358
|
+
}) : null,
|
|
359
|
+
hasPluginMenu ? /* @__PURE__ */ jsxs(Menu.Root, { children: [/* @__PURE__ */ jsxs(Button, {
|
|
360
|
+
type: "button",
|
|
361
|
+
variant: "ghost",
|
|
362
|
+
color: "neutral",
|
|
363
|
+
size: "md",
|
|
364
|
+
render: /* @__PURE__ */ jsx(Menu.Trigger, { unstyled: true }),
|
|
365
|
+
"aria-label": "Connect plugins",
|
|
366
|
+
children: [/* @__PURE__ */ jsx("span", { children: "Connect plugins" }), /* @__PURE__ */ jsxs(AppIcon.Stack, {
|
|
367
|
+
"aria-hidden": "true",
|
|
368
|
+
children: [/* @__PURE__ */ jsx(AppIcon.Root, {
|
|
369
|
+
size: "sm",
|
|
370
|
+
variant: "surface",
|
|
371
|
+
children: /* @__PURE__ */ jsx(SlackIcon, {})
|
|
372
|
+
}), /* @__PURE__ */ jsx(AppIcon.Root, {
|
|
373
|
+
size: "sm",
|
|
374
|
+
variant: "surface",
|
|
375
|
+
children: /* @__PURE__ */ jsx(DiscordIcon, {})
|
|
376
|
+
})]
|
|
377
|
+
})]
|
|
378
|
+
}), /* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(Menu.Positioner, {
|
|
379
|
+
side: "bottom",
|
|
380
|
+
align: "start",
|
|
381
|
+
sideOffset: 4,
|
|
382
|
+
children: /* @__PURE__ */ jsxs(Menu.Popup, {
|
|
383
|
+
"aria-label": "Plugins",
|
|
384
|
+
"data-recipe": "wide-scroll-picker",
|
|
385
|
+
children: [/* @__PURE__ */ jsx(McpServerPickerItems, {
|
|
386
|
+
actions: [...start.discord ? [{
|
|
387
|
+
id: "discord",
|
|
388
|
+
icon: /* @__PURE__ */ jsx(DiscordIcon, {}),
|
|
389
|
+
label: start.discord.configured ? "Discord" : "Connect Discord",
|
|
390
|
+
description: start.discord.description ?? (start.discord.configured ? "Connected" : "Talk to this employee from Discord"),
|
|
391
|
+
onSelect: start.discord.onSelect
|
|
392
|
+
}] : [], ...start.slack ? [{
|
|
393
|
+
id: "slack",
|
|
394
|
+
icon: /* @__PURE__ */ jsx(SlackIcon, {}),
|
|
395
|
+
label: start.slack.configured ? "Slack" : "Connect Slack",
|
|
396
|
+
description: start.slack.description ?? (start.slack.configured ? "Connected" : "Talk to this employee from Slack"),
|
|
397
|
+
onSelect: start.slack.onSelect
|
|
398
|
+
}] : []],
|
|
399
|
+
servers: plugins?.servers ?? [],
|
|
400
|
+
mcp: plugins?.mcp,
|
|
401
|
+
onConnect: plugins?.onConnect,
|
|
402
|
+
onDisconnect: plugins?.onDisconnect
|
|
403
|
+
}), /* @__PURE__ */ jsx(McpServerPickerAction, {
|
|
404
|
+
icon: /* @__PURE__ */ jsx(BoxIcon, {}),
|
|
405
|
+
label: "Browse plugins",
|
|
406
|
+
description: plugins?.onConnect ? "Find and connect supported tools" : "See what this browser is connected to",
|
|
407
|
+
render: renderLink({
|
|
408
|
+
kind: "view",
|
|
409
|
+
view: "plugins"
|
|
410
|
+
})
|
|
411
|
+
})]
|
|
412
|
+
})
|
|
413
|
+
}) })] }) : null
|
|
414
|
+
] });
|
|
415
|
+
}
|
|
416
|
+
function startStarters(brandName, start, onShowGuide) {
|
|
417
|
+
return {
|
|
418
|
+
"aria-label": "Suggested prompts",
|
|
419
|
+
items: [
|
|
420
|
+
{
|
|
421
|
+
id: "capability-guide",
|
|
422
|
+
label: `See what ${brandName} can do`,
|
|
423
|
+
icon: /* @__PURE__ */ jsx(InfoIcon, {}),
|
|
424
|
+
muted: true
|
|
425
|
+
},
|
|
426
|
+
...start.suggestionsError ? [{
|
|
427
|
+
id: "retry-suggestions",
|
|
428
|
+
label: "Try generating suggestions again",
|
|
429
|
+
icon: /* @__PURE__ */ jsx(InfoIcon, {}),
|
|
430
|
+
muted: true
|
|
431
|
+
}] : [],
|
|
432
|
+
...start.suggestions?.map((suggestion, index) => ({
|
|
433
|
+
id: `suggestion:${index}:${suggestion.value}:${suggestion.label}`,
|
|
434
|
+
label: suggestion.label,
|
|
435
|
+
icon: suggestion.value.startsWith("/") ? /* @__PURE__ */ jsx(BoxIcon, {}) : suggestion.value.startsWith("@") ? /* @__PURE__ */ jsx(McpIcon, {}) : /* @__PURE__ */ jsx(EyeIcon, {})
|
|
436
|
+
})) ?? []
|
|
437
|
+
],
|
|
438
|
+
onSelect: (item) => {
|
|
439
|
+
if (item.id === "capability-guide") {
|
|
440
|
+
onShowGuide();
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
if (item.id === "retry-suggestions") {
|
|
444
|
+
start.onRetrySuggestions?.();
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
const suggestion = start.suggestions?.find((candidate, index) => item.id === `suggestion:${index}:${candidate.value}:${candidate.label}`);
|
|
448
|
+
if (suggestion) start.onSubmit({
|
|
449
|
+
text: suggestion.value,
|
|
450
|
+
files: []
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
function BackToChat({ renderLink }) {
|
|
456
|
+
return /* @__PURE__ */ jsx(AppTopBar.Link, {
|
|
457
|
+
label: "Back to chat",
|
|
458
|
+
render: renderLink({
|
|
459
|
+
kind: "view",
|
|
460
|
+
view: "chat"
|
|
461
|
+
}),
|
|
462
|
+
children: /* @__PURE__ */ jsx(ArrowLeftIcon, {})
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
function employeeMessages({ agentRun, brandName, guideOpen, hasConversation, hostMessages, onShowGuide, plugins, renderLink, start }) {
|
|
466
|
+
const onSubmit = hostMessages?.draft?.onSubmit ?? start?.onSubmit;
|
|
467
|
+
const draft = hasConversation ? hostMessages?.draft : onSubmit ? {
|
|
468
|
+
messages: hostMessages?.draft?.messages ?? [],
|
|
469
|
+
onSubmit,
|
|
470
|
+
status: hostMessages?.draft?.status
|
|
471
|
+
} : hostMessages?.draft;
|
|
472
|
+
return {
|
|
473
|
+
placeholder: "How can I help you today?",
|
|
474
|
+
approvalsEnabled: false,
|
|
475
|
+
...hostMessages,
|
|
476
|
+
startScreen: start ? {
|
|
477
|
+
lead: guideOpen ? /* @__PURE__ */ jsx(CapabilityGuide, {
|
|
478
|
+
brandName,
|
|
479
|
+
start
|
|
480
|
+
}) : void 0,
|
|
481
|
+
composerTray: /* @__PURE__ */ jsx(StartComposerTray, {
|
|
482
|
+
plugins,
|
|
483
|
+
renderLink,
|
|
484
|
+
start
|
|
485
|
+
}),
|
|
486
|
+
starters: guideOpen ? void 0 : startStarters(brandName, start, onShowGuide)
|
|
487
|
+
} : hostMessages?.startScreen,
|
|
488
|
+
draft,
|
|
489
|
+
showComposer: agentRun ? false : hostMessages?.showComposer
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* The employee side panel: icon-and-tooltip chrome, start screen, schedules,
|
|
494
|
+
* conversation plus workbench. Hosts hydrate conversation, workspace,
|
|
495
|
+
* plugins, and callables. Storybook is the place to iterate the chrome.
|
|
496
|
+
*/
|
|
497
|
+
function ThinkSidepanel({ agentRun, appBarLeading, brand, className, companion, connectingLabel, conversation, follow, identity, live, messages, modelSetup, onDeleteThread, onModel, onSignOut, passkeyVault, plugins, renderLink, schedules, sourceKey, start, status = "ready", thread, threads = EMPTY_THREADS, view, workspace, ...props }) {
|
|
498
|
+
const [identityOpen, setIdentityOpen] = React.useState(false);
|
|
499
|
+
const [guideOpen, setGuideOpen] = React.useState(false);
|
|
500
|
+
if (status !== "ready") return /* @__PURE__ */ jsx("div", {
|
|
501
|
+
className: cx("think-sidepanel", className),
|
|
502
|
+
"data-status": status,
|
|
503
|
+
...props,
|
|
504
|
+
children: /* @__PURE__ */ jsx(GateScreen, {
|
|
505
|
+
brand,
|
|
506
|
+
connectingLabel,
|
|
507
|
+
identity,
|
|
508
|
+
modelSetup,
|
|
509
|
+
status
|
|
510
|
+
})
|
|
511
|
+
});
|
|
512
|
+
const overflow = /* @__PURE__ */ jsx(OverflowMenu, {
|
|
513
|
+
companion,
|
|
514
|
+
follow: thread && !agentRun ? follow : void 0,
|
|
515
|
+
identityEmail: identity?.email,
|
|
516
|
+
onIdentity: identity ? () => setIdentityOpen(true) : void 0,
|
|
517
|
+
onModel,
|
|
518
|
+
onSignOut,
|
|
519
|
+
passkeyVault,
|
|
520
|
+
renderLink
|
|
521
|
+
});
|
|
522
|
+
const identityDialog = identity ? /* @__PURE__ */ jsx(IdentityDialog, {
|
|
523
|
+
identity,
|
|
524
|
+
open: identityOpen,
|
|
525
|
+
onOpenChange: setIdentityOpen
|
|
526
|
+
}) : null;
|
|
527
|
+
const newThread = thread && !agentRun ? /* @__PURE__ */ jsx(AppTopBar.Link, {
|
|
528
|
+
label: "New thread",
|
|
529
|
+
render: renderLink({ kind: "new-thread" }),
|
|
530
|
+
children: /* @__PURE__ */ jsx(PencilIcon, {})
|
|
531
|
+
}) : void 0;
|
|
532
|
+
const chatLeading = newThread || view === "chat" && appBarLeading ? /* @__PURE__ */ jsxs(Fragment, { children: [newThread, view === "chat" ? appBarLeading : null] }) : void 0;
|
|
533
|
+
const chatMessages = employeeMessages({
|
|
534
|
+
agentRun,
|
|
535
|
+
brandName: brand.name,
|
|
536
|
+
guideOpen,
|
|
537
|
+
hasConversation: Boolean(conversation),
|
|
538
|
+
hostMessages: messages,
|
|
539
|
+
onShowGuide: () => setGuideOpen(true),
|
|
540
|
+
plugins,
|
|
541
|
+
renderLink,
|
|
542
|
+
start
|
|
543
|
+
});
|
|
544
|
+
if (view === "live") return /* @__PURE__ */ jsxs("div", {
|
|
545
|
+
className: cx("think-sidepanel", className),
|
|
546
|
+
"data-view": "live",
|
|
547
|
+
...props,
|
|
548
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
549
|
+
className: "think-sidepanel__live",
|
|
550
|
+
children: [/* @__PURE__ */ jsxs(AppTopBar.Root, {
|
|
551
|
+
"aria-label": "Live view controls",
|
|
552
|
+
children: [/* @__PURE__ */ jsx(AppTopBar.Leading, { children: /* @__PURE__ */ jsx(BackToChat, { renderLink }) }), /* @__PURE__ */ jsx(AppTopBar.Title, { children: "Live view" })]
|
|
553
|
+
}), live]
|
|
554
|
+
}), identityDialog]
|
|
555
|
+
});
|
|
556
|
+
if (view === "schedules") return /* @__PURE__ */ jsxs("div", {
|
|
557
|
+
className: cx("think-sidepanel", className),
|
|
558
|
+
"data-view": "schedules",
|
|
559
|
+
...props,
|
|
560
|
+
children: [schedules?.editor ? /* @__PURE__ */ jsx("div", {
|
|
561
|
+
className: "think-sidepanel__editor",
|
|
562
|
+
children: schedules.editor
|
|
563
|
+
}) : schedules ? /* @__PURE__ */ jsx(ThinkRoutineLibrary, {
|
|
564
|
+
bar: {
|
|
565
|
+
leading: /* @__PURE__ */ jsx(BackToChat, { renderLink }),
|
|
566
|
+
primary: overflow
|
|
567
|
+
},
|
|
568
|
+
routines: schedules.routines,
|
|
569
|
+
showOwner: false,
|
|
570
|
+
selectedRoutineId: schedules.selectedRoutineId,
|
|
571
|
+
error: schedules.error,
|
|
572
|
+
renderRoutineLink: (routine) => renderLink({
|
|
573
|
+
kind: "routine",
|
|
574
|
+
routineId: routine.id
|
|
575
|
+
}),
|
|
576
|
+
createRoutineLink: renderLink({ kind: "create-routine" }),
|
|
577
|
+
renderEditRoutineLink: (routine) => renderLink({
|
|
578
|
+
kind: "edit-routine",
|
|
579
|
+
routineId: routine.id
|
|
580
|
+
}),
|
|
581
|
+
renderRunLink: (routine, run) => renderLink({
|
|
582
|
+
kind: "routine-run",
|
|
583
|
+
routineId: routine.id,
|
|
584
|
+
runId: getThinkExecutionRunId(run)
|
|
585
|
+
}),
|
|
586
|
+
onRunRoutine: schedules.onRunRoutine,
|
|
587
|
+
onRoutineEnabledChange: schedules.onRoutineEnabledChange,
|
|
588
|
+
onDeleteRoutine: schedules.onDeleteRoutine
|
|
589
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
590
|
+
className: "think-sidepanel__gate",
|
|
591
|
+
children: /* @__PURE__ */ jsx(EmptyState, {
|
|
592
|
+
title: "Schedules",
|
|
593
|
+
description: "No schedules to show."
|
|
594
|
+
})
|
|
595
|
+
}), identityDialog]
|
|
596
|
+
});
|
|
597
|
+
const workbenchView = view === "plugins" ? "plugins" : view === "files" ? "files" : "chat";
|
|
598
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
599
|
+
className: cx("think-sidepanel", className),
|
|
600
|
+
"data-view": view,
|
|
601
|
+
...props,
|
|
602
|
+
children: [/* @__PURE__ */ jsx(ThinkFullApp, {
|
|
603
|
+
conversation,
|
|
604
|
+
renderAgentToolRunLink: (run) => renderLink({
|
|
605
|
+
kind: "agent-run",
|
|
606
|
+
runId: run.runId
|
|
607
|
+
}),
|
|
608
|
+
bar: {
|
|
609
|
+
title: agentRun ? /* @__PURE__ */ jsxs("span", {
|
|
610
|
+
className: "think-sidepanel__run-title",
|
|
611
|
+
children: [/* @__PURE__ */ jsx(NaniteMark, {}), /* @__PURE__ */ jsx("span", {
|
|
612
|
+
className: "sigvelo-truncate",
|
|
613
|
+
children: agentRun.title
|
|
614
|
+
})]
|
|
615
|
+
}) : thread?.title ?? "New chat",
|
|
616
|
+
leading: agentRun ? /* @__PURE__ */ jsx(AppTopBar.Link, {
|
|
617
|
+
label: "Back to parent conversation",
|
|
618
|
+
render: thread ? renderLink({
|
|
619
|
+
kind: "thread",
|
|
620
|
+
threadId: thread.id
|
|
621
|
+
}) : renderLink({
|
|
622
|
+
kind: "view",
|
|
623
|
+
view: "chat"
|
|
624
|
+
}),
|
|
625
|
+
children: /* @__PURE__ */ jsx(ArrowLeftIcon, {})
|
|
626
|
+
}) : chatLeading,
|
|
627
|
+
compactLeading: !agentRun && (view === "files" || view === "plugins") ? /* @__PURE__ */ jsx(BackToChat, { renderLink }) : void 0,
|
|
628
|
+
actions: agentRun?.running && agentRun.onCancel ? /* @__PURE__ */ jsx(AppTopBar.Button, {
|
|
629
|
+
label: "Cancel run",
|
|
630
|
+
onClick: agentRun.onCancel,
|
|
631
|
+
children: /* @__PURE__ */ jsx(SquareIcon, {})
|
|
632
|
+
}) : void 0,
|
|
633
|
+
primary: overflow,
|
|
634
|
+
views: null
|
|
635
|
+
},
|
|
636
|
+
threadStatusSummary: agentRun ? void 0 : summarizeThinkThreads(threads),
|
|
637
|
+
sourceKey,
|
|
638
|
+
workspace: agentRun ? void 0 : workspace,
|
|
639
|
+
plugins: agentRun ? void 0 : plugins,
|
|
640
|
+
view: workbenchView,
|
|
641
|
+
threadSidebar: agentRun ? void 0 : ({ closeSidebarOnCompact }) => /* @__PURE__ */ jsx(ThinkThreadPicker, {
|
|
642
|
+
threads,
|
|
643
|
+
renderThreadLink: (item) => renderLink({
|
|
644
|
+
kind: "thread",
|
|
645
|
+
threadId: item.id
|
|
646
|
+
}),
|
|
647
|
+
createThreadLink: renderLink({ kind: "new-thread" }),
|
|
648
|
+
onSelect: closeSidebarOnCompact,
|
|
649
|
+
onDelete: onDeleteThread
|
|
650
|
+
}),
|
|
651
|
+
messages: chatMessages
|
|
652
|
+
}), identityDialog]
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
//#endregion
|
|
656
|
+
export { ThinkSidepanel };
|
|
@@ -42,11 +42,10 @@ interface ThinkThreadPickerProps extends Omit<React.HTMLAttributes<HTMLElement>,
|
|
|
42
42
|
*/
|
|
43
43
|
renderThreadLink: (thread: ThinkThreadItem) => React.ReactElement;
|
|
44
44
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* one: a thread created on click is an empty thread until someone writes in it.
|
|
45
|
+
* App-authored TanStack Router Link to the new-thread screen. A thread
|
|
46
|
+
* created on click is an empty thread until someone writes in it.
|
|
48
47
|
*/
|
|
49
|
-
|
|
48
|
+
createThreadLink?: React.ReactElement;
|
|
50
49
|
/**
|
|
51
50
|
* Notified on unmodified primary activation. The link still navigates — the
|
|
52
51
|
* route is the selection — so this is for side effects such as closing a
|
|
@@ -77,7 +76,7 @@ declare function ThinkThreadStatusIndicators({
|
|
|
77
76
|
declare function ThinkThreadPicker({
|
|
78
77
|
threads,
|
|
79
78
|
renderThreadLink,
|
|
80
|
-
|
|
79
|
+
createThreadLink,
|
|
81
80
|
onSelect,
|
|
82
81
|
onDelete,
|
|
83
82
|
className,
|