@mcp-b/react-components 0.14.2 → 0.16.1
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/AgentActivity-BNUNrP9O.d.ts +36 -0
- package/dist/{AgentChat-DQkqt82e.d.ts → AgentChat-CrlpbvQJ.d.ts} +58 -6
- package/dist/{CodeBlock-DUh9WOGo.d.ts → CodeBlock-BRajW4QU.d.ts} +1 -1
- package/dist/{CodeBlock-BUFXG8HW.js → CodeBlock-BmB4Xaqq.js} +15 -4
- package/dist/{FileTree-mpEIcfzA.js → FileTree-CkVbIMWV.js} +82 -89
- package/dist/Message-BkMdE3bS.js +375 -0
- package/dist/{ModelSelector-CPCpFAUt.js → ModelSelector-SlJNgwKY.js} +2 -2
- package/dist/{PromptInput-ClNqBiIw.d.ts → PromptInput-BWTuXMOD.d.ts} +123 -5
- package/dist/ResponsiveSidebarShell-Dd9DCcBT.d.ts +67 -0
- package/dist/{Select-Dl_vF_Bt.d.ts → Select-BeEsefzh.d.ts} +12 -2
- package/dist/{ThinkChat-BPcehdbP.js → ThinkChat-CzC-zNGA.js} +24 -36
- package/dist/{ThinkChatActivity-BmwuIigx.d.ts → ThinkChatActivity-BFQnb2ct.d.ts} +3 -10
- package/dist/ThinkChatActivitySummary-BPmu9a-c.d.ts +39 -0
- package/dist/{ThinkChatToolParts-CDEjqS6A.d.ts → ThinkChatToolParts-CSzVwMXf.d.ts} +13 -3
- package/dist/ThinkExecutionRun-ChhWhOoU.d.ts +30 -0
- package/dist/Toggle-CAAlNl-M.d.ts +69 -0
- package/dist/ToggleGroup-8hPv-b69.d.ts +73 -0
- package/dist/Workspace-D39LxGvP.d.ts +62 -0
- package/dist/WorkspaceFile-DOZkPwzu.d.ts +106 -0
- package/dist/WorkspaceFileView-rSN_yT0L.js +744 -0
- package/dist/WorkspaceLink-DIPbXrUM.js +337 -0
- package/dist/WorkspaceLink-DK1DWMHe.d.ts +89 -0
- package/dist/components/Activity.d.ts +27 -1
- package/dist/components/Activity.js +33 -15
- package/dist/components/AgentActivity.d.ts +2 -0
- package/dist/components/AgentActivity.js +45 -0
- package/dist/components/AgentActivityPreview.d.ts +46 -0
- package/dist/components/AgentActivityPreview.js +94 -0
- package/dist/components/AgentAttention.d.ts +73 -0
- package/dist/components/AgentAttention.js +85 -0
- package/dist/components/AgentChat.d.ts +2 -2
- package/dist/components/AgentChat.js +224 -200
- package/dist/components/AgentChatMessageEditor.d.ts +29 -0
- package/dist/components/AgentChatMessageEditor.js +92 -0
- package/dist/components/AgentChatTurnError.d.ts +17 -0
- package/dist/components/AgentChatTurnError.js +40 -0
- package/dist/components/AgentConnection.d.ts +12 -17
- package/dist/components/AgentConnection.js +99 -91
- package/dist/components/AppFrame.d.ts +24 -0
- package/dist/components/AppFrame.js +25 -0
- package/dist/components/AppTopBar.d.ts +71 -0
- package/dist/components/AppTopBar.js +82 -0
- package/dist/components/Artifact.js +1 -1
- package/dist/components/BrowserLiveView.js +1 -1
- package/dist/components/BrowserReplay.js +1 -1
- package/dist/components/BrowserRunPanel.js +1 -1
- package/dist/components/Card.d.ts +3 -0
- package/dist/components/Card.js +2 -1
- package/dist/components/ChainOfThought.d.ts +1 -1
- package/dist/components/ChainOfThought.js +1 -1
- package/dist/components/ChatGptSignInScreen.js +2 -2
- package/dist/components/Checkbox.js +5 -13
- package/dist/components/CheckboxGroup.d.ts +58 -2
- package/dist/components/CheckboxGroup.js +59 -1
- package/dist/components/CodeBlock.d.ts +1 -1
- package/dist/components/CodeBlock.js +1 -1
- package/dist/components/CodexModelSelector.js +1 -1
- package/dist/components/Commit.js +2 -2
- package/dist/components/ContextMenu.js +1 -1
- package/dist/components/Conversation.js +1 -1
- package/dist/components/DescriptionList.d.ts +12 -0
- package/dist/components/DescriptionList.js +11 -0
- package/dist/components/DescriptionListParts.d.ts +37 -0
- package/dist/components/DescriptionListParts.js +35 -0
- package/dist/components/EnvironmentVariables.js +2 -2
- package/dist/components/Fieldset.d.ts +13 -1
- package/dist/components/Fieldset.js +11 -2
- package/dist/components/FileTree.js +1 -1
- package/dist/components/IconButton.d.ts +33 -0
- package/dist/components/IconButton.js +27 -0
- package/dist/components/McpConnectionRequest.d.ts +44 -0
- package/dist/components/McpConnectionRequest.js +122 -0
- package/dist/components/McpServerPicker.d.ts +48 -23
- package/dist/components/McpServerPicker.js +238 -189
- package/dist/components/Menubar.js +1 -1
- package/dist/components/Message.d.ts +1 -0
- package/dist/components/Message.js +1 -285
- package/dist/components/MessageScroller.js +1 -1
- package/dist/components/ModelSelector.js +1 -1
- package/dist/components/Pricing.d.ts +37 -0
- package/dist/components/Pricing.js +17 -0
- package/dist/components/PricingBillingToggle.d.ts +23 -0
- package/dist/components/PricingBillingToggle.js +86 -0
- package/dist/components/PricingConfirmationDialog.d.ts +25 -0
- package/dist/components/PricingConfirmationDialog.js +57 -0
- package/dist/components/PricingFAQ.d.ts +18 -0
- package/dist/components/PricingFAQ.js +27 -0
- package/dist/components/PricingPage.d.ts +2 -38
- package/dist/components/PricingPage.js +39 -359
- package/dist/components/PricingPlanCard.d.ts +22 -0
- package/dist/components/PricingPlanCard.js +109 -0
- package/dist/components/PricingUsageCalculator.d.ts +22 -0
- package/dist/components/PricingUsageCalculator.js +96 -0
- package/dist/components/PromptInput.d.ts +2 -2
- package/dist/components/PromptInput.js +210 -15
- package/dist/components/Queue.js +1 -1
- package/dist/components/Reasoning.d.ts +2 -1
- package/dist/components/Reasoning.js +14 -29
- package/dist/components/ResizableSidePanel.d.ts +57 -0
- package/dist/components/ResizableSidePanel.js +151 -0
- package/dist/components/ResponsiveSidebarShell.d.ts +2 -0
- package/dist/components/ResponsiveSidebarShell.js +129 -0
- package/dist/components/Select.d.ts +2 -2
- package/dist/components/Select.js +11 -2
- package/dist/components/Slider.d.ts +13 -1
- package/dist/components/Slider.js +11 -0
- package/dist/components/Sources.js +1 -1
- package/dist/components/Stepper.d.ts +4 -0
- package/dist/components/Stepper.js +5 -3
- package/dist/components/SubagentRun.d.ts +18 -19
- package/dist/components/SubagentRun.js +25 -18
- package/dist/components/SubagentRunIndicator.d.ts +22 -0
- package/dist/components/SubagentRunIndicator.js +33 -0
- package/dist/components/SubagentRunList.d.ts +25 -0
- package/dist/components/SubagentRunList.js +26 -0
- package/dist/components/SubagentRunSelector.d.ts +47 -0
- package/dist/components/SubagentRunSelector.js +55 -0
- package/dist/components/Task.js +1 -1
- package/dist/components/Terminal.js +2 -2
- package/dist/components/TestResults.js +1 -1
- package/dist/components/Textarea.d.ts +21 -0
- package/dist/components/Textarea.js +19 -0
- package/dist/components/ThemeModeControl.d.ts +24 -0
- package/dist/components/ThemeModeControl.js +52 -0
- package/dist/components/ThemeProvider.d.ts +38 -0
- package/dist/components/ThemeProvider.js +80 -0
- package/dist/components/ThinkChat.d.ts +29 -6
- package/dist/components/ThinkChat.js +7 -4
- package/dist/components/ThinkChatActivity.d.ts +3 -2
- package/dist/components/ThinkChatActivity.js +12 -318
- package/dist/components/ThinkChatActivitySummary.d.ts +2 -0
- package/dist/components/ThinkChatActivitySummary.js +421 -0
- package/dist/components/ThinkChatToolPanels.d.ts +7 -5
- package/dist/components/ThinkChatToolPanels.js +70 -8
- package/dist/components/ThinkChatToolParts.d.ts +2 -2
- package/dist/components/ThinkChatToolParts.js +36 -10
- package/dist/components/ThinkExecutionDetail.d.ts +20 -0
- package/dist/components/ThinkExecutionDetail.js +80 -0
- package/dist/components/ThinkExecutionRun.d.ts +2 -0
- package/dist/components/ThinkExecutionRun.js +72 -0
- package/dist/components/ThinkExecutionStatus.d.ts +22 -0
- package/dist/components/ThinkExecutionStatus.js +36 -0
- package/dist/components/ThinkExecutionWorkbench.d.ts +7 -0
- package/dist/components/ThinkExecutionWorkbench.js +69 -225
- package/dist/components/ThinkFullApp.d.ts +58 -14
- package/dist/components/ThinkFullApp.js +154 -160
- package/dist/components/ThinkFullAppViewSwitch.d.ts +31 -0
- package/dist/components/ThinkFullAppViewSwitch.js +34 -0
- package/dist/components/ThinkRoutine.d.ts +36 -0
- package/dist/components/ThinkRoutine.js +15 -0
- package/dist/components/ThinkRoutineBrowser.d.ts +25 -0
- package/dist/components/ThinkRoutineBrowser.js +156 -0
- package/dist/components/ThinkRoutineDetail.d.ts +24 -0
- package/dist/components/ThinkRoutineDetail.js +102 -0
- package/dist/components/ThinkRoutineForm.d.ts +32 -0
- package/dist/components/ThinkRoutineForm.js +151 -0
- package/dist/components/ThinkRoutineLibrary.d.ts +74 -0
- package/dist/components/ThinkRoutineLibrary.js +178 -0
- package/dist/components/ThinkRoutineRuns.d.ts +24 -0
- package/dist/components/ThinkRoutineRuns.js +68 -0
- package/dist/components/ThinkThreadPicker.d.ts +18 -1
- package/dist/components/ThinkThreadPicker.js +51 -5
- package/dist/components/ThinkThreadShell.d.ts +12 -9
- package/dist/components/ThinkThreadShell.js +17 -137
- package/dist/components/Toggle.d.ts +1 -68
- package/dist/components/ToggleGroup.d.ts +1 -72
- package/dist/components/Tooltip.d.ts +3 -1
- package/dist/components/Tooltip.js +4 -2
- package/dist/components/WebPreview.js +1 -1
- package/dist/components/Workspace.d.ts +2 -0
- package/dist/components/Workspace.js +424 -0
- package/dist/components/WorkspaceBrowser.d.ts +32 -0
- package/dist/components/WorkspaceBrowser.js +103 -0
- package/dist/components/WorkspaceExplorer.d.ts +12 -79
- package/dist/components/WorkspaceExplorer.js +116 -330
- package/dist/components/WorkspaceFile.d.ts +2 -0
- package/dist/components/WorkspaceFile.js +195 -0
- package/dist/components/WorkspaceFileView.d.ts +26 -0
- package/dist/components/WorkspaceFileView.js +2 -0
- package/dist/components/WorkspaceHeader.d.ts +35 -0
- package/dist/components/WorkspaceHeader.js +51 -0
- package/dist/components/WorkspaceLink.d.ts +2 -0
- package/dist/components/WorkspaceLink.js +2 -0
- package/dist/components/icons.d.ts +2 -2
- package/dist/components/icons.js +2 -2
- package/dist/{copy-button-DUMLYdsk.js → copy-button-Dejn5heL.js} +1 -1
- package/dist/icons-CpfUer49.js +85 -0
- package/dist/{icons-CUCz_Sft.d.ts → icons-GQd1xF4e.d.ts} +51 -1
- package/dist/styles/activity-header.css +75 -0
- package/dist/styles/activity.css +49 -63
- package/dist/styles/agent-activity-preview-overlay.css +80 -0
- package/dist/styles/agent-activity-preview.css +233 -0
- package/dist/styles/agent-attention.css +128 -0
- package/dist/styles/agent-chat.css +133 -4
- package/dist/styles/agent-connection.css +9 -9
- package/dist/styles/alert-dialog.css +11 -11
- package/dist/styles/app-frame.css +15 -0
- package/dist/styles/app-top-bar.css +102 -0
- package/dist/styles/avatar.css +0 -1
- package/dist/styles/browser-control-overlay.css +184 -0
- package/dist/styles/card.css +29 -8
- package/dist/styles/chain-of-thought.css +5 -5
- package/dist/styles/checkbox-group.css +69 -0
- package/dist/styles/codex-model-selector.css +3 -3
- package/dist/styles/combobox.css +2 -1
- package/dist/styles/context-menu.css +1 -1
- package/dist/styles/description-list.css +50 -0
- package/dist/styles/dialog.css +11 -11
- package/dist/styles/field.css +14 -14
- package/dist/styles/fieldset.css +15 -4
- package/dist/styles/index.css +14 -2
- package/dist/styles/mcp-connection-request.css +60 -0
- package/dist/styles/mcp-server-picker.css +96 -68
- package/dist/styles/menu.css +1 -1
- package/dist/styles/message.css +4 -43
- package/dist/styles/model-selector.css +18 -12
- package/dist/styles/popover.css +9 -9
- package/dist/styles/preview-card.css +1 -1
- package/dist/styles/pricing-page.css +21 -27
- package/dist/styles/prompt-input.css +225 -32
- package/dist/styles/reasoning.css +1 -55
- package/dist/styles/recipes.css +50 -24
- package/dist/styles/resizable-side-panel.css +66 -0
- package/dist/styles/responsive-sidebar-shell.css +169 -0
- package/dist/styles/select.css +13 -3
- package/dist/styles/sources.css +6 -6
- package/dist/styles/stepper.css +13 -0
- package/dist/styles/streamdown.css +0 -4
- package/dist/styles/subagent-run.css +59 -42
- package/dist/styles/task.css +17 -10
- package/dist/styles/test-results.css +17 -10
- package/dist/styles/textarea.css +20 -0
- package/dist/styles/theme-mode-control.css +72 -0
- package/dist/styles/think-execution-status.css +49 -0
- package/dist/styles/think-execution-workbench.css +16 -80
- package/dist/styles/think-full-app.css +143 -128
- package/dist/styles/think-routine-library.css +491 -0
- package/dist/styles/think-thread-picker.css +47 -3
- package/dist/styles/toast.css +6 -6
- package/dist/styles/toggle-group.css +7 -0
- package/dist/styles/tooltip.css +1 -1
- package/dist/styles/workspace-explorer.css +516 -64
- package/dist/utils/mcp-server-catalog.d.ts +82 -78
- package/dist/utils/mcp-server-catalog.js +64 -41
- package/dist/utils/structured-code.d.ts +1 -1
- package/dist/utils/theme.d.ts +22 -0
- package/dist/utils/theme.js +55 -0
- package/package.json +34 -28
- package/dist/icons-Ba9THQKz.js +0 -64
- package/dist/styles/think-resize-handle.css +0 -33
- package/dist/styles/think-thread-shell.css +0 -219
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import { t as cx } from "./class-names-9UtZwb0J.js";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
//#region src/components/_internal/workspace-navigation-context.tsx
|
|
5
|
+
const WorkspaceNavigationContext = React.createContext(null);
|
|
6
|
+
function useWorkspaceNavigationContext() {
|
|
7
|
+
return React.use(WorkspaceNavigationContext);
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/components/_internal/workspace-navigation-restoration.tsx
|
|
11
|
+
const WorkspaceNavigationRestorationContext = React.createContext(null);
|
|
12
|
+
/**
|
|
13
|
+
* Owns entry-keyed presentation state unless an ancestor already provides it.
|
|
14
|
+
* This lets a full application share restoration between chat and files while
|
|
15
|
+
* keeping a standalone WorkspaceExplorer self-contained.
|
|
16
|
+
*/
|
|
17
|
+
function WorkspaceNavigationRestorationBoundary({ children }) {
|
|
18
|
+
const parent = React.use(WorkspaceNavigationRestorationContext);
|
|
19
|
+
const restorationsRef = React.useRef(/* @__PURE__ */ new Map());
|
|
20
|
+
const localValue = React.useMemo(() => ({
|
|
21
|
+
get: (entryKey) => restorationsRef.current.get(entryKey),
|
|
22
|
+
recordFocus: (entryKey, destination, scope) => {
|
|
23
|
+
const current = restorationsRef.current.get(entryKey);
|
|
24
|
+
restorationsRef.current.set(entryKey, {
|
|
25
|
+
...current,
|
|
26
|
+
focusDestination: destination,
|
|
27
|
+
focusScope: scope
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
recordScroll: (entryKey, scrollTop) => {
|
|
31
|
+
const current = restorationsRef.current.get(entryKey);
|
|
32
|
+
restorationsRef.current.set(entryKey, {
|
|
33
|
+
...current,
|
|
34
|
+
scrollTop
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}), []);
|
|
38
|
+
if (parent) return children;
|
|
39
|
+
return /* @__PURE__ */ jsx(WorkspaceNavigationRestorationContext, {
|
|
40
|
+
value: localValue,
|
|
41
|
+
children
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function findDestinationLink(root, destination) {
|
|
45
|
+
if (destination.kind !== "file") return null;
|
|
46
|
+
return [...root.querySelectorAll("[data-workspace-link=\"file\"]")].find((candidate) => candidate.dataset.workspacePath === destination.path && (candidate.dataset.workspaceDestinationFragment || null) === destination.fragment) ?? null;
|
|
47
|
+
}
|
|
48
|
+
/** Restores a link in a named surface, including when that surface renders asynchronously. */
|
|
49
|
+
function WorkspaceNavigationFocusRestorer({ entryKey, rootRef, scope }) {
|
|
50
|
+
const restoration = useWorkspaceNavigationRestoration();
|
|
51
|
+
const handledEntryRef = React.useRef(null);
|
|
52
|
+
React.useEffect(() => {
|
|
53
|
+
if (handledEntryRef.current !== entryKey) handledEntryRef.current = null;
|
|
54
|
+
if (handledEntryRef.current === entryKey) return;
|
|
55
|
+
const saved = restoration?.get(entryKey);
|
|
56
|
+
if (!saved?.focusDestination || saved.focusScope !== scope) return;
|
|
57
|
+
const focusDestination = saved.focusDestination;
|
|
58
|
+
const root = rootRef.current;
|
|
59
|
+
if (!root) return;
|
|
60
|
+
const restore = () => {
|
|
61
|
+
const surface = [...root.matches("[data-workspace-restoration-scope]") ? [root] : [], ...root.querySelectorAll("[data-workspace-restoration-scope]")].find((candidate) => candidate.dataset.workspaceRestorationScope === scope);
|
|
62
|
+
const target = surface ? findDestinationLink(surface, focusDestination) : null;
|
|
63
|
+
if (!target) return false;
|
|
64
|
+
target.focus({ preventScroll: true });
|
|
65
|
+
handledEntryRef.current = entryKey;
|
|
66
|
+
return true;
|
|
67
|
+
};
|
|
68
|
+
if (restore()) return;
|
|
69
|
+
const observer = new MutationObserver(() => {
|
|
70
|
+
if (restore()) observer.disconnect();
|
|
71
|
+
});
|
|
72
|
+
observer.observe(root, {
|
|
73
|
+
childList: true,
|
|
74
|
+
subtree: true
|
|
75
|
+
});
|
|
76
|
+
return () => observer.disconnect();
|
|
77
|
+
}, [
|
|
78
|
+
entryKey,
|
|
79
|
+
restoration,
|
|
80
|
+
rootRef,
|
|
81
|
+
scope
|
|
82
|
+
]);
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
function useWorkspaceNavigationRestoration() {
|
|
86
|
+
return React.use(WorkspaceNavigationRestorationContext);
|
|
87
|
+
}
|
|
88
|
+
function useRequiredWorkspaceNavigationRestoration() {
|
|
89
|
+
const restoration = useWorkspaceNavigationRestoration();
|
|
90
|
+
if (!restoration) throw new Error("Workspace navigation restoration is unavailable outside its boundary.");
|
|
91
|
+
return restoration;
|
|
92
|
+
}
|
|
93
|
+
//#endregion
|
|
94
|
+
//#region src/components/WorkspaceLink.tsx
|
|
95
|
+
const WORKSPACE_URL_ORIGIN = "https://workspace.invalid";
|
|
96
|
+
const EXTERNAL_PROTOCOLS = /* @__PURE__ */ new Set([
|
|
97
|
+
"http:",
|
|
98
|
+
"https:",
|
|
99
|
+
"mailto:",
|
|
100
|
+
"tel:"
|
|
101
|
+
]);
|
|
102
|
+
const UNSAFE_PROTOCOLS = /* @__PURE__ */ new Set([
|
|
103
|
+
"data:",
|
|
104
|
+
"file:",
|
|
105
|
+
"javascript:",
|
|
106
|
+
"vbscript:"
|
|
107
|
+
]);
|
|
108
|
+
const URL_SCHEME = /^[a-zA-Z][a-zA-Z\d+.-]*:/;
|
|
109
|
+
function hasInvalidPathCharacter(value) {
|
|
110
|
+
for (const character of value) {
|
|
111
|
+
const codePoint = character.codePointAt(0) ?? 0;
|
|
112
|
+
if (character === "\\" || codePoint <= 31 || codePoint === 127) return true;
|
|
113
|
+
}
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
function decodeUrlPart(value) {
|
|
117
|
+
try {
|
|
118
|
+
return decodeURIComponent(value);
|
|
119
|
+
} catch {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function canonicalizeAbsolutePath(path) {
|
|
124
|
+
if (!path.startsWith("/") || hasInvalidPathCharacter(path)) return null;
|
|
125
|
+
const segments = [];
|
|
126
|
+
for (const segment of path.split("/")) {
|
|
127
|
+
if (!segment || segment === ".") continue;
|
|
128
|
+
if (segment === "..") segments.pop();
|
|
129
|
+
else segments.push(segment);
|
|
130
|
+
}
|
|
131
|
+
return `/${segments.join("/")}`;
|
|
132
|
+
}
|
|
133
|
+
function normalizeRoot(root) {
|
|
134
|
+
if (!root || hasInvalidPathCharacter(root)) return null;
|
|
135
|
+
const pathname = canonicalizeAbsolutePath(root);
|
|
136
|
+
if (!pathname) return null;
|
|
137
|
+
return pathname === "/" ? pathname : pathname.replace(/\/+$/, "");
|
|
138
|
+
}
|
|
139
|
+
function isWithinRoot(path, root) {
|
|
140
|
+
return root === "/" || path === root || path.startsWith(`${root}/`);
|
|
141
|
+
}
|
|
142
|
+
function getPathSegments(path) {
|
|
143
|
+
return path === "/" ? [] : path.slice(1).split("/");
|
|
144
|
+
}
|
|
145
|
+
function resolveLocalPath(rawPath, root, base, normalizedBase) {
|
|
146
|
+
const decodedPath = decodeUrlPart(rawPath);
|
|
147
|
+
if (decodedPath === null || hasInvalidPathCharacter(decodedPath)) return { reason: "invalid-path" };
|
|
148
|
+
if (decodedPath === "") return { path: normalizedBase };
|
|
149
|
+
const rootSegments = getPathSegments(root);
|
|
150
|
+
let segments;
|
|
151
|
+
let remainingPath;
|
|
152
|
+
if (decodedPath.startsWith("/")) {
|
|
153
|
+
segments = [...rootSegments];
|
|
154
|
+
remainingPath = root !== "/" && (decodedPath === root || decodedPath.startsWith(`${root}/`)) ? decodedPath.slice(root.length) : decodedPath.slice(1);
|
|
155
|
+
} else {
|
|
156
|
+
segments = getPathSegments(base.kind === "directory" ? normalizedBase : normalizedBase.slice(0, normalizedBase.lastIndexOf("/")) || "/");
|
|
157
|
+
remainingPath = decodedPath;
|
|
158
|
+
}
|
|
159
|
+
for (const segment of remainingPath.split("/")) {
|
|
160
|
+
if (!segment || segment === ".") continue;
|
|
161
|
+
if (segment === "..") {
|
|
162
|
+
if (segments.length <= rootSegments.length) return { reason: "outside-workspace" };
|
|
163
|
+
segments.pop();
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
segments.push(segment);
|
|
167
|
+
}
|
|
168
|
+
return { path: `/${segments.join("/")}` };
|
|
169
|
+
}
|
|
170
|
+
function invalid(href, reason) {
|
|
171
|
+
return {
|
|
172
|
+
kind: "invalid",
|
|
173
|
+
href,
|
|
174
|
+
reason
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
function getExternalDestination(href) {
|
|
178
|
+
try {
|
|
179
|
+
const protocol = new URL(href.startsWith("//") ? `https:${href}` : href).protocol.toLowerCase();
|
|
180
|
+
if (UNSAFE_PROTOCOLS.has(protocol) || !EXTERNAL_PROTOCOLS.has(protocol)) return invalid(href, "unsafe-protocol");
|
|
181
|
+
return {
|
|
182
|
+
kind: "external",
|
|
183
|
+
href
|
|
184
|
+
};
|
|
185
|
+
} catch {
|
|
186
|
+
return invalid(href, "invalid-path");
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/** Resolve a Markdown link to a validated workspace file, external URL, or unavailable target. */
|
|
190
|
+
function resolveWorkspaceLink({ href, root, base }) {
|
|
191
|
+
const normalizedRoot = normalizeRoot(root);
|
|
192
|
+
const normalizedBase = canonicalizeAbsolutePath(base.path);
|
|
193
|
+
const trimmedHref = href.trim();
|
|
194
|
+
if (!normalizedRoot || !normalizedBase || !isWithinRoot(normalizedBase, normalizedRoot) || !trimmedHref || hasInvalidPathCharacter(href)) return invalid(href, "invalid-path");
|
|
195
|
+
if (trimmedHref.startsWith("//")) return getExternalDestination(trimmedHref);
|
|
196
|
+
if (URL_SCHEME.test(trimmedHref)) return getExternalDestination(trimmedHref);
|
|
197
|
+
if (trimmedHref.startsWith("#") && base.kind === "directory") return invalid(href, "fragment-without-file");
|
|
198
|
+
const fragmentIndex = trimmedHref.indexOf("#");
|
|
199
|
+
const pathAndQuery = fragmentIndex === -1 ? trimmedHref : trimmedHref.slice(0, fragmentIndex);
|
|
200
|
+
if (pathAndQuery.includes("?")) return invalid(href, "unsupported-query");
|
|
201
|
+
const rawPath = pathAndQuery;
|
|
202
|
+
const rawFragment = fragmentIndex === -1 ? null : trimmedHref.slice(fragmentIndex + 1);
|
|
203
|
+
const fragment = rawFragment === null || rawFragment === "" ? null : decodeUrlPart(rawFragment);
|
|
204
|
+
if (rawFragment !== null && rawFragment !== "" && fragment === null || fragment !== null && hasInvalidPathCharacter(fragment)) return invalid(href, "invalid-path");
|
|
205
|
+
const localPath = resolveLocalPath(rawPath, normalizedRoot, base, normalizedBase);
|
|
206
|
+
if ("reason" in localPath) return invalid(href, localPath.reason);
|
|
207
|
+
if (!isWithinRoot(localPath.path, normalizedRoot)) return invalid(href, "outside-workspace");
|
|
208
|
+
return {
|
|
209
|
+
kind: "file",
|
|
210
|
+
path: localPath.path,
|
|
211
|
+
fragment
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function getAdapterHref(navigation, destination) {
|
|
215
|
+
try {
|
|
216
|
+
const rawHref = navigation.createHref(destination);
|
|
217
|
+
if (hasInvalidPathCharacter(rawHref)) return null;
|
|
218
|
+
const href = rawHref.trim();
|
|
219
|
+
if (!href) return null;
|
|
220
|
+
const protocol = new URL(href, WORKSPACE_URL_ORIGIN).protocol.toLowerCase();
|
|
221
|
+
if (UNSAFE_PROTOCOLS.has(protocol)) return null;
|
|
222
|
+
return href;
|
|
223
|
+
} catch {
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
function WorkspaceNavigationProvider({ children, root, base, navigation }) {
|
|
228
|
+
return /* @__PURE__ */ jsx(WorkspaceNavigationContext, {
|
|
229
|
+
value: React.useMemo(() => ({
|
|
230
|
+
root,
|
|
231
|
+
base,
|
|
232
|
+
navigation
|
|
233
|
+
}), [
|
|
234
|
+
base.kind,
|
|
235
|
+
base.path,
|
|
236
|
+
navigation,
|
|
237
|
+
root
|
|
238
|
+
]),
|
|
239
|
+
children
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
function UnavailableWorkspaceLink({ children, className }) {
|
|
243
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
244
|
+
className: cx("workspace-link workspace-link--invalid", className),
|
|
245
|
+
"data-workspace-link": "invalid",
|
|
246
|
+
children: [
|
|
247
|
+
children,
|
|
248
|
+
/* @__PURE__ */ jsx("span", {
|
|
249
|
+
className: "workspace-link__invalid-mark",
|
|
250
|
+
"aria-hidden": "true",
|
|
251
|
+
children: "↛"
|
|
252
|
+
}),
|
|
253
|
+
/* @__PURE__ */ jsx("span", {
|
|
254
|
+
className: "workspace-link__visually-hidden",
|
|
255
|
+
children: " (link unavailable)"
|
|
256
|
+
})
|
|
257
|
+
]
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Markdown-compatible anchor that resolves local files through the nearest
|
|
262
|
+
* workspace navigation provider while preserving native link behavior.
|
|
263
|
+
*/
|
|
264
|
+
function WorkspaceFileLink({ children, className, download, href = "", node: _node, onClick, rel, target, ...props }) {
|
|
265
|
+
const workspace = useWorkspaceNavigationContext();
|
|
266
|
+
const restoration = useWorkspaceNavigationRestoration();
|
|
267
|
+
if (!workspace) return /* @__PURE__ */ jsx("a", {
|
|
268
|
+
className,
|
|
269
|
+
download,
|
|
270
|
+
href,
|
|
271
|
+
onClick,
|
|
272
|
+
rel,
|
|
273
|
+
target,
|
|
274
|
+
...props,
|
|
275
|
+
children
|
|
276
|
+
});
|
|
277
|
+
const resolved = resolveWorkspaceLink({
|
|
278
|
+
href,
|
|
279
|
+
root: workspace.root,
|
|
280
|
+
base: workspace.base
|
|
281
|
+
});
|
|
282
|
+
if (resolved.kind === "invalid") return /* @__PURE__ */ jsx(UnavailableWorkspaceLink, {
|
|
283
|
+
className,
|
|
284
|
+
children
|
|
285
|
+
});
|
|
286
|
+
if (resolved.kind === "external") {
|
|
287
|
+
const externalTarget = target ?? "_blank";
|
|
288
|
+
return /* @__PURE__ */ jsxs("a", {
|
|
289
|
+
className: cx("workspace-link workspace-link--external", className),
|
|
290
|
+
"data-streamdown": "link",
|
|
291
|
+
download,
|
|
292
|
+
href: resolved.href,
|
|
293
|
+
onClick,
|
|
294
|
+
rel: rel ?? (externalTarget === "_blank" ? "noopener noreferrer" : void 0),
|
|
295
|
+
target: externalTarget,
|
|
296
|
+
...props,
|
|
297
|
+
children: [children, externalTarget === "_blank" ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
298
|
+
className: "workspace-link__external-mark",
|
|
299
|
+
"aria-hidden": "true",
|
|
300
|
+
children: "↗"
|
|
301
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
302
|
+
className: "workspace-link__visually-hidden",
|
|
303
|
+
children: " (opens in a new tab)"
|
|
304
|
+
})] }) : null]
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
const adapterHref = getAdapterHref(workspace.navigation, resolved);
|
|
308
|
+
if (!adapterHref) return /* @__PURE__ */ jsx(UnavailableWorkspaceLink, {
|
|
309
|
+
className,
|
|
310
|
+
children
|
|
311
|
+
});
|
|
312
|
+
const handleClick = (event) => {
|
|
313
|
+
onClick?.(event);
|
|
314
|
+
const actualTarget = event.currentTarget.target.toLowerCase();
|
|
315
|
+
if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey || event.currentTarget.hasAttribute("download") || actualTarget !== "" && actualTarget !== "_self") return;
|
|
316
|
+
event.preventDefault();
|
|
317
|
+
const focusScope = event.currentTarget.closest("[data-workspace-restoration-scope]")?.dataset.workspaceRestorationScope;
|
|
318
|
+
restoration?.recordFocus(workspace.navigation.current.key, resolved, focusScope);
|
|
319
|
+
workspace.navigation.navigate(resolved);
|
|
320
|
+
};
|
|
321
|
+
return /* @__PURE__ */ jsx("a", {
|
|
322
|
+
className: cx("workspace-link workspace-link--file", className),
|
|
323
|
+
"data-streamdown": "link",
|
|
324
|
+
"data-workspace-link": "file",
|
|
325
|
+
"data-workspace-destination-fragment": resolved.fragment ?? "",
|
|
326
|
+
"data-workspace-path": resolved.path,
|
|
327
|
+
download,
|
|
328
|
+
href: adapterHref,
|
|
329
|
+
onClick: handleClick,
|
|
330
|
+
rel,
|
|
331
|
+
target,
|
|
332
|
+
...props,
|
|
333
|
+
children
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
//#endregion
|
|
337
|
+
export { WorkspaceNavigationRestorationBoundary as a, useWorkspaceNavigationContext as c, WorkspaceNavigationFocusRestorer as i, WorkspaceNavigationProvider as n, useRequiredWorkspaceNavigationRestoration as o, resolveWorkspaceLink as r, useWorkspaceNavigationRestoration as s, WorkspaceFileLink as t };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/components/WorkspaceLink.d.ts
|
|
4
|
+
type WorkspaceDestination = {
|
|
5
|
+
kind: "files";
|
|
6
|
+
} | {
|
|
7
|
+
kind: "file";
|
|
8
|
+
path: string;
|
|
9
|
+
fragment: string | null;
|
|
10
|
+
};
|
|
11
|
+
interface WorkspaceNavigationEntry {
|
|
12
|
+
key: string;
|
|
13
|
+
destination: WorkspaceDestination;
|
|
14
|
+
}
|
|
15
|
+
interface WorkspaceNavigationAdapter {
|
|
16
|
+
current: WorkspaceNavigationEntry;
|
|
17
|
+
createHref(destination: WorkspaceDestination): string;
|
|
18
|
+
navigate(destination: WorkspaceDestination, options?: {
|
|
19
|
+
replace?: boolean;
|
|
20
|
+
}): void;
|
|
21
|
+
canGoBack: boolean;
|
|
22
|
+
canGoForward: boolean;
|
|
23
|
+
goBack(): void;
|
|
24
|
+
goForward(): void;
|
|
25
|
+
}
|
|
26
|
+
type WorkspaceLinkBase = {
|
|
27
|
+
kind: "directory";
|
|
28
|
+
path: string;
|
|
29
|
+
} | {
|
|
30
|
+
kind: "file";
|
|
31
|
+
path: string;
|
|
32
|
+
};
|
|
33
|
+
interface WorkspaceExternalDestination {
|
|
34
|
+
kind: "external";
|
|
35
|
+
href: string;
|
|
36
|
+
}
|
|
37
|
+
interface WorkspaceInvalidDestination {
|
|
38
|
+
kind: "invalid";
|
|
39
|
+
href: string;
|
|
40
|
+
reason: "fragment-without-file" | "invalid-adapter-href" | "invalid-path" | "outside-workspace" | "unsafe-protocol" | "unsupported-query";
|
|
41
|
+
}
|
|
42
|
+
type WorkspaceLinkResolution = Extract<WorkspaceDestination, {
|
|
43
|
+
kind: "file";
|
|
44
|
+
}> | WorkspaceExternalDestination | WorkspaceInvalidDestination;
|
|
45
|
+
interface ResolveWorkspaceLinkOptions {
|
|
46
|
+
href: string;
|
|
47
|
+
/** Workspace boundary. A leading `/` resolves from this root. */
|
|
48
|
+
root: string;
|
|
49
|
+
/** Directory for chat links or containing file for file-preview links. */
|
|
50
|
+
base: WorkspaceLinkBase;
|
|
51
|
+
}
|
|
52
|
+
interface WorkspaceNavigationProviderProps {
|
|
53
|
+
children: React.ReactNode;
|
|
54
|
+
root: string;
|
|
55
|
+
base: WorkspaceLinkBase;
|
|
56
|
+
navigation: WorkspaceNavigationAdapter;
|
|
57
|
+
}
|
|
58
|
+
/** Resolve a Markdown link to a validated workspace file, external URL, or unavailable target. */
|
|
59
|
+
declare function resolveWorkspaceLink({
|
|
60
|
+
href,
|
|
61
|
+
root,
|
|
62
|
+
base
|
|
63
|
+
}: ResolveWorkspaceLinkOptions): WorkspaceLinkResolution;
|
|
64
|
+
declare function WorkspaceNavigationProvider({
|
|
65
|
+
children,
|
|
66
|
+
root,
|
|
67
|
+
base,
|
|
68
|
+
navigation
|
|
69
|
+
}: WorkspaceNavigationProviderProps): React.JSX.Element;
|
|
70
|
+
interface WorkspaceFileLinkProps extends React.ComponentProps<"a"> {
|
|
71
|
+
node?: unknown;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Markdown-compatible anchor that resolves local files through the nearest
|
|
75
|
+
* workspace navigation provider while preserving native link behavior.
|
|
76
|
+
*/
|
|
77
|
+
declare function WorkspaceFileLink({
|
|
78
|
+
children,
|
|
79
|
+
className,
|
|
80
|
+
download,
|
|
81
|
+
href,
|
|
82
|
+
node: _node,
|
|
83
|
+
onClick,
|
|
84
|
+
rel,
|
|
85
|
+
target,
|
|
86
|
+
...props
|
|
87
|
+
}: WorkspaceFileLinkProps): React.JSX.Element;
|
|
88
|
+
//#endregion
|
|
89
|
+
export { WorkspaceFileLinkProps as a, WorkspaceLinkResolution as c, WorkspaceNavigationProvider as d, WorkspaceNavigationProviderProps as f, WorkspaceFileLink as i, WorkspaceNavigationAdapter as l, WorkspaceDestination as n, WorkspaceInvalidDestination as o, resolveWorkspaceLink as p, WorkspaceExternalDestination as r, WorkspaceLinkBase as s, ResolveWorkspaceLinkOptions as t, WorkspaceNavigationEntry as u };
|
|
@@ -43,6 +43,32 @@ interface ActivityTriggerProps extends Omit<React.ComponentProps<typeof Collapsi
|
|
|
43
43
|
/** Optional leading icon for the header. */
|
|
44
44
|
icon?: React.ReactNode;
|
|
45
45
|
}
|
|
46
|
+
interface ActivityHeaderProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, "children"> {
|
|
47
|
+
/** Current one-line activity label. */
|
|
48
|
+
label?: React.ReactNode;
|
|
49
|
+
/** Optional leading activity icon. */
|
|
50
|
+
icon?: React.ReactNode;
|
|
51
|
+
/** Optional trailing affordance supplied by the interactive owner. */
|
|
52
|
+
trailing?: React.ReactNode;
|
|
53
|
+
/** While true, the label uses the shared streaming treatment. */
|
|
54
|
+
isStreaming?: boolean;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Presentation-only activity header. It deliberately has no click or
|
|
58
|
+
* disclosure behavior so a transcript, app shell, or injected preview can
|
|
59
|
+
* provide the correct interaction semantics around the same visual.
|
|
60
|
+
*/
|
|
61
|
+
declare function ActivityHeader({
|
|
62
|
+
className,
|
|
63
|
+
icon,
|
|
64
|
+
isStreaming,
|
|
65
|
+
label,
|
|
66
|
+
trailing,
|
|
67
|
+
ref,
|
|
68
|
+
...props
|
|
69
|
+
}: ActivityHeaderProps & {
|
|
70
|
+
ref?: React.Ref<HTMLSpanElement>;
|
|
71
|
+
}): React.JSX.Element;
|
|
46
72
|
/**
|
|
47
73
|
* Clickable header line that toggles the activity log. The label shimmers
|
|
48
74
|
* while the parent Activity is streaming.
|
|
@@ -148,4 +174,4 @@ declare function ActivityPanel({
|
|
|
148
174
|
ref?: React.Ref<HTMLDivElement>;
|
|
149
175
|
}): React.JSX.Element;
|
|
150
176
|
//#endregion
|
|
151
|
-
export { Activity, ActivityContent, ActivityContentProps, ActivityItem, ActivityItemGroup, ActivityItemGroupProps, ActivityItemProps, ActivityOutput, ActivityOutputProps, ActivityPanel, ActivityPanelProps, ActivityProps, ActivityText, ActivityTextProps, ActivityTrigger, ActivityTriggerProps };
|
|
177
|
+
export { Activity, ActivityContent, ActivityContentProps, ActivityHeader, ActivityHeaderProps, ActivityItem, ActivityItemGroup, ActivityItemGroupProps, ActivityItemProps, ActivityOutput, ActivityOutputProps, ActivityPanel, ActivityPanelProps, ActivityProps, ActivityText, ActivityTextProps, ActivityTrigger, ActivityTriggerProps };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Collapsible } from "./Collapsible.js";
|
|
2
2
|
import { t as cx } from "../class-names-9UtZwb0J.js";
|
|
3
|
-
import {
|
|
3
|
+
import { l as ChevronRightIcon } from "../icons-CpfUer49.js";
|
|
4
4
|
import "react";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
//#region src/components/Activity.tsx
|
|
@@ -35,6 +35,31 @@ function Activity({ className, isStreaming = false, defaultOpen = false, ref, ..
|
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
|
+
* Presentation-only activity header. It deliberately has no click or
|
|
39
|
+
* disclosure behavior so a transcript, app shell, or injected preview can
|
|
40
|
+
* provide the correct interaction semantics around the same visual.
|
|
41
|
+
*/
|
|
42
|
+
function ActivityHeader({ className, icon, isStreaming = false, label = "Working…", trailing, ref, ...props }) {
|
|
43
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
44
|
+
ref,
|
|
45
|
+
className: cx("activity__header", className),
|
|
46
|
+
"data-streaming": isStreaming || void 0,
|
|
47
|
+
...props,
|
|
48
|
+
children: [
|
|
49
|
+
icon ? /* @__PURE__ */ jsx("span", {
|
|
50
|
+
className: "activity__item-icon",
|
|
51
|
+
"aria-hidden": "true",
|
|
52
|
+
children: icon
|
|
53
|
+
}) : null,
|
|
54
|
+
/* @__PURE__ */ jsx("span", {
|
|
55
|
+
className: "activity__header-label",
|
|
56
|
+
children: label
|
|
57
|
+
}),
|
|
58
|
+
trailing
|
|
59
|
+
]
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
38
63
|
* Clickable header line that toggles the activity log. The label shimmers
|
|
39
64
|
* while the parent Activity is streaming.
|
|
40
65
|
*/
|
|
@@ -46,27 +71,20 @@ function ActivityTrigger({ className, label = "Working…", icon, children, ref,
|
|
|
46
71
|
unstyled: true,
|
|
47
72
|
children
|
|
48
73
|
});
|
|
49
|
-
return /* @__PURE__ */
|
|
74
|
+
return /* @__PURE__ */ jsx(Collapsible.Trigger, {
|
|
50
75
|
ref,
|
|
51
76
|
className: cx("activity__trigger", className),
|
|
52
77
|
...props,
|
|
53
78
|
unstyled: true,
|
|
54
|
-
children:
|
|
55
|
-
icon
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
children: icon
|
|
59
|
-
}) : null,
|
|
60
|
-
/* @__PURE__ */ jsx("span", {
|
|
61
|
-
className: "activity__trigger-label",
|
|
62
|
-
children: label
|
|
63
|
-
}),
|
|
64
|
-
/* @__PURE__ */ jsx("span", {
|
|
79
|
+
children: /* @__PURE__ */ jsx(ActivityHeader, {
|
|
80
|
+
icon,
|
|
81
|
+
label,
|
|
82
|
+
trailing: /* @__PURE__ */ jsx("span", {
|
|
65
83
|
className: "activity__trigger-icon",
|
|
66
84
|
"aria-hidden": "true",
|
|
67
85
|
children: /* @__PURE__ */ jsx(ChevronRightIcon, {})
|
|
68
86
|
})
|
|
69
|
-
|
|
87
|
+
})
|
|
70
88
|
});
|
|
71
89
|
}
|
|
72
90
|
/** The collapsible log of ActivityItem children. */
|
|
@@ -182,4 +200,4 @@ function ActivityPanel({ className, label, text, status, error, children, ref, .
|
|
|
182
200
|
});
|
|
183
201
|
}
|
|
184
202
|
//#endregion
|
|
185
|
-
export { Activity, ActivityContent, ActivityItem, ActivityItemGroup, ActivityOutput, ActivityPanel, ActivityText, ActivityTrigger };
|
|
203
|
+
export { Activity, ActivityContent, ActivityHeader, ActivityItem, ActivityItemGroup, ActivityOutput, ActivityPanel, ActivityText, ActivityTrigger };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as AgentActivityIconProps, i as AgentActivityIconKind, n as AgentActivityFaviconProps, o as AgentActivityMode, r as AgentActivityIcon, s as AgentActivitySummary, t as AgentActivityFavicon } from "../AgentActivity-BNUNrP9O.js";
|
|
2
|
+
export { AgentActivityFavicon, AgentActivityFaviconProps, AgentActivityIcon, AgentActivityIconKind, AgentActivityIconProps, AgentActivityMode, AgentActivitySummary };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { C as LinkIcon, G as TerminalIcon, J as WrenchIcon, N as PencilIcon, R as SearchIcon, S as InfoIcon, k as MonitorIcon, q as WarningIcon, v as FileIcon } from "../icons-CpfUer49.js";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
//#region src/components/AgentActivity.tsx
|
|
5
|
+
/** Built-in icon vocabulary shared by AI SDK activity and Agents SDK state summaries. */
|
|
6
|
+
function AgentActivityIcon({ kind }) {
|
|
7
|
+
switch (kind) {
|
|
8
|
+
case "thought": return /* @__PURE__ */ jsx(InfoIcon, {});
|
|
9
|
+
case "read": return /* @__PURE__ */ jsx(FileIcon, {});
|
|
10
|
+
case "edit": return /* @__PURE__ */ jsx(PencilIcon, {});
|
|
11
|
+
case "search": return /* @__PURE__ */ jsx(SearchIcon, {});
|
|
12
|
+
case "web": return /* @__PURE__ */ jsx(LinkIcon, {});
|
|
13
|
+
case "command": return /* @__PURE__ */ jsx(TerminalIcon, {});
|
|
14
|
+
case "browser": return /* @__PURE__ */ jsx(MonitorIcon, {});
|
|
15
|
+
case "approval": return /* @__PURE__ */ jsx(WarningIcon, {});
|
|
16
|
+
default: return /* @__PURE__ */ jsx(WrenchIcon, {});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/** Site favicon for URL-backed activity, with the shared icon vocabulary as fallback. */
|
|
20
|
+
function AgentActivityFavicon({ fallbackKind = "web", url }) {
|
|
21
|
+
const src = faviconHref(url);
|
|
22
|
+
const [failed, setFailed] = React.useState(false);
|
|
23
|
+
React.useEffect(() => setFailed(false), [src]);
|
|
24
|
+
if (!src || failed) return /* @__PURE__ */ jsx(AgentActivityIcon, { kind: fallbackKind });
|
|
25
|
+
return /* @__PURE__ */ jsx("img", {
|
|
26
|
+
className: "activity__favicon",
|
|
27
|
+
src,
|
|
28
|
+
alt: "",
|
|
29
|
+
loading: "lazy",
|
|
30
|
+
decoding: "async",
|
|
31
|
+
referrerPolicy: "no-referrer",
|
|
32
|
+
onError: () => setFailed(true)
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function faviconHref(url) {
|
|
36
|
+
try {
|
|
37
|
+
const parsed = new URL(url);
|
|
38
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return null;
|
|
39
|
+
return new URL("/favicon.ico", parsed.origin).href;
|
|
40
|
+
} catch {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { AgentActivityFavicon, AgentActivityIcon };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { n as WorkspaceDestination } from "../WorkspaceLink-DK1DWMHe.js";
|
|
2
|
+
import { s as AgentActivitySummary } from "../AgentActivity-BNUNrP9O.js";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/components/AgentActivityPreview.d.ts
|
|
6
|
+
/** The three conditions that make an agent relevant to the transient preview. */
|
|
7
|
+
type AgentActivityPreviewStatus = "running" | "input-required" | "unviewed";
|
|
8
|
+
interface AgentActivityPreviewFavicon {
|
|
9
|
+
src: string;
|
|
10
|
+
label: string;
|
|
11
|
+
}
|
|
12
|
+
type AgentActivityPreviewItem = Omit<AgentActivitySummary, "mode"> & {
|
|
13
|
+
id: string;
|
|
14
|
+
status: AgentActivityPreviewStatus;
|
|
15
|
+
favicons?: readonly AgentActivityPreviewFavicon[];
|
|
16
|
+
};
|
|
17
|
+
interface AgentActivityPreviewProps extends Omit<React.HTMLAttributes<HTMLElement>, "children" | "onSelect"> {
|
|
18
|
+
/** Current agent summaries to show in the transient preview. */
|
|
19
|
+
items: readonly AgentActivityPreviewItem[];
|
|
20
|
+
/** Opens the selected agent by its stable id. */
|
|
21
|
+
onSelect: (id: string) => void;
|
|
22
|
+
/** Opens a projected file target in the selected agent's workspace. */
|
|
23
|
+
onOpenWorkspaceFile?: (id: string, destination: Extract<WorkspaceDestination, {
|
|
24
|
+
kind: "file";
|
|
25
|
+
}>) => void;
|
|
26
|
+
/** Hides the complete preview when the host supports dismissal. */
|
|
27
|
+
onDismiss?: () => void;
|
|
28
|
+
/** Product mark shown beside the agent rows. */
|
|
29
|
+
brandIcon?: React.ReactNode;
|
|
30
|
+
}
|
|
31
|
+
/** Compact multi-agent preview for a page overlay or secondary application rail. */
|
|
32
|
+
declare function AgentActivityPreview({
|
|
33
|
+
"aria-label": ariaLabel,
|
|
34
|
+
brandIcon,
|
|
35
|
+
className,
|
|
36
|
+
items,
|
|
37
|
+
onDismiss,
|
|
38
|
+
onOpenWorkspaceFile,
|
|
39
|
+
onSelect,
|
|
40
|
+
ref,
|
|
41
|
+
...props
|
|
42
|
+
}: AgentActivityPreviewProps & {
|
|
43
|
+
ref?: React.Ref<HTMLElement>;
|
|
44
|
+
}): React.JSX.Element | null;
|
|
45
|
+
//#endregion
|
|
46
|
+
export { AgentActivityPreview, AgentActivityPreviewFavicon, AgentActivityPreviewItem, AgentActivityPreviewProps, AgentActivityPreviewStatus };
|