mcp-app-studio 0.3.2
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/README.md +152 -0
- package/bin/mcp-app-studio.js +5 -0
- package/dist/bridge-BOSEqpaS.d.ts +66 -0
- package/dist/chunk-4LAH4JH6.js +47 -0
- package/dist/chunk-KRCGOYZ5.js +16 -0
- package/dist/chunk-L2RRNF7V.js +140 -0
- package/dist/chunk-QO43ZGJI.js +174 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +579 -0
- package/dist/core/index.d.ts +445 -0
- package/dist/core/index.js +16 -0
- package/dist/index.d.ts +508 -0
- package/dist/index.js +358 -0
- package/dist/platforms/chatgpt/index.d.ts +158 -0
- package/dist/platforms/chatgpt/index.js +149 -0
- package/dist/platforms/mcp/index.d.ts +37 -0
- package/dist/platforms/mcp/index.js +159 -0
- package/package.json +124 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
import { Platform, ExtendedBridge, HostContext, HostCapabilities, ToolResult, DisplayMode, ContentBlock, FeatureKey } from './core/index.js';
|
|
2
|
+
export { AudioContentBlock, CHATGPT_CAPABILITIES, ChatMessage, ContainerDimensions, ContentBlockAnnotations, ContentBlockIcon, HostBridge, HostContextChangedCallback, HostStyles, ImageContentBlock, MCP_CAPABILITIES, ResourceContentBlock, ResourceLinkContentBlock, TeardownCallback, TextContentBlock, Theme, ToolCancelledCallback, ToolInputCallback, ToolInputPartialCallback, ToolResultCallback, hasFeature, imageBlock, textBlock } from './core/index.js';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
import { ReactNode } from 'react';
|
|
5
|
+
import { A as AppCapabilities } from './bridge-BOSEqpaS.js';
|
|
6
|
+
import '@modelcontextprotocol/ext-apps';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Detection result with detailed information about what was checked.
|
|
10
|
+
*/
|
|
11
|
+
interface DetectionResult {
|
|
12
|
+
/** The detected platform */
|
|
13
|
+
platform: Platform;
|
|
14
|
+
/** What marker was found (if any) */
|
|
15
|
+
detectedBy: string | null;
|
|
16
|
+
/** All markers that were checked */
|
|
17
|
+
checks: {
|
|
18
|
+
windowOpenai: boolean;
|
|
19
|
+
mcpUrlParam: boolean;
|
|
20
|
+
mcpWindowProp: boolean;
|
|
21
|
+
mcpDataAttr: boolean;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Detects the current platform with detailed results.
|
|
26
|
+
* Useful for debugging platform detection issues.
|
|
27
|
+
*
|
|
28
|
+
* @returns Detection result with platform and diagnostic info
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* const result = detectPlatformDetailed();
|
|
33
|
+
* console.log('Platform:', result.platform);
|
|
34
|
+
* console.log('Detected by:', result.detectedBy);
|
|
35
|
+
* console.log('Checks:', result.checks);
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
declare function detectPlatformDetailed(): DetectionResult;
|
|
39
|
+
/**
|
|
40
|
+
* Detects the current platform the widget is running on.
|
|
41
|
+
*
|
|
42
|
+
* Detection priority:
|
|
43
|
+
* 1. `window.openai` exists → ChatGPT
|
|
44
|
+
* 2. URL has `?mcp-host` param → MCP
|
|
45
|
+
* 3. `window.__MCP_HOST__` exists → MCP
|
|
46
|
+
* 4. iframe has `data-mcp-host` attribute → MCP
|
|
47
|
+
* 5. None of the above → unknown
|
|
48
|
+
*
|
|
49
|
+
* **Debugging tip:** Set `window.__CHATGPT_APP_DEBUG__ = true` before
|
|
50
|
+
* loading your widget to see detailed detection logs in the console.
|
|
51
|
+
*
|
|
52
|
+
* @returns The detected platform: "chatgpt", "mcp", or "unknown"
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* const platform = detectPlatform();
|
|
57
|
+
* if (platform === 'unknown') {
|
|
58
|
+
* console.log('Running in development mode or unsupported host');
|
|
59
|
+
* }
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
declare function detectPlatform(): Platform;
|
|
63
|
+
/**
|
|
64
|
+
* Returns true if running inside ChatGPT.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```ts
|
|
68
|
+
* if (isChatGPT()) {
|
|
69
|
+
* // Use ChatGPT-specific features
|
|
70
|
+
* }
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
declare function isChatGPT(): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Returns true if running inside an MCP host (e.g., Claude Desktop).
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* if (isMCP()) {
|
|
80
|
+
* // Use MCP-specific features
|
|
81
|
+
* }
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
declare function isMCP(): boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Enable debug mode for platform detection.
|
|
87
|
+
* Logs detailed information about what markers are being checked.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```ts
|
|
91
|
+
* import { enableDebugMode } from 'mcp-app-studio';
|
|
92
|
+
*
|
|
93
|
+
* // Enable before your app initializes
|
|
94
|
+
* enableDebugMode();
|
|
95
|
+
*
|
|
96
|
+
* // Now detection will log to console
|
|
97
|
+
* const platform = detectPlatform();
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
declare function enableDebugMode(): void;
|
|
101
|
+
/**
|
|
102
|
+
* Disable debug mode for platform detection.
|
|
103
|
+
*/
|
|
104
|
+
declare function disableDebugMode(): void;
|
|
105
|
+
|
|
106
|
+
interface UniversalProviderProps {
|
|
107
|
+
children: ReactNode;
|
|
108
|
+
appInfo?: {
|
|
109
|
+
name: string;
|
|
110
|
+
version: string;
|
|
111
|
+
};
|
|
112
|
+
appCapabilities?: AppCapabilities;
|
|
113
|
+
}
|
|
114
|
+
declare function UniversalProvider({ children, appInfo, appCapabilities, }: UniversalProviderProps): react_jsx_runtime.JSX.Element | null;
|
|
115
|
+
declare function useUniversalBridge(): ExtendedBridge | null;
|
|
116
|
+
declare function usePlatform(): Platform;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Returns the current host context with environment information.
|
|
120
|
+
* Updates automatically when the host context changes.
|
|
121
|
+
*
|
|
122
|
+
* @returns The host context object, or null if not connected
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```tsx
|
|
126
|
+
* function MyWidget() {
|
|
127
|
+
* const context = useHostContext();
|
|
128
|
+
*
|
|
129
|
+
* if (!context) return <div>Loading...</div>;
|
|
130
|
+
*
|
|
131
|
+
* return (
|
|
132
|
+
* <div>
|
|
133
|
+
* <p>Theme: {context.theme}</p>
|
|
134
|
+
* <p>Locale: {context.locale}</p>
|
|
135
|
+
* <p>Display mode: {context.displayMode}</p>
|
|
136
|
+
* </div>
|
|
137
|
+
* );
|
|
138
|
+
* }
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
declare function useHostContext(): HostContext | null;
|
|
142
|
+
/**
|
|
143
|
+
* Returns the current color theme ("light" or "dark").
|
|
144
|
+
* Defaults to "light" if theme is not available.
|
|
145
|
+
*
|
|
146
|
+
* @returns Current theme
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```tsx
|
|
150
|
+
* function MyWidget() {
|
|
151
|
+
* const theme = useTheme();
|
|
152
|
+
*
|
|
153
|
+
* return (
|
|
154
|
+
* <div className={theme === 'dark' ? 'bg-gray-900 text-white' : 'bg-white text-black'}>
|
|
155
|
+
* Content
|
|
156
|
+
* </div>
|
|
157
|
+
* );
|
|
158
|
+
* }
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
declare function useTheme(): "light" | "dark";
|
|
162
|
+
/**
|
|
163
|
+
* Returns the capabilities supported by the current host platform.
|
|
164
|
+
* Use this to conditionally enable features based on platform support.
|
|
165
|
+
*
|
|
166
|
+
* @returns Host capabilities object, or null if not connected
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```tsx
|
|
170
|
+
* function MyWidget() {
|
|
171
|
+
* const capabilities = useCapabilities();
|
|
172
|
+
*
|
|
173
|
+
* return (
|
|
174
|
+
* <div>
|
|
175
|
+
* {capabilities?.widgetState && (
|
|
176
|
+
* <button>Save State (ChatGPT only)</button>
|
|
177
|
+
* )}
|
|
178
|
+
* {capabilities?.modelContext && (
|
|
179
|
+
* <button>Update Context (MCP only)</button>
|
|
180
|
+
* )}
|
|
181
|
+
* </div>
|
|
182
|
+
* );
|
|
183
|
+
* }
|
|
184
|
+
* ```
|
|
185
|
+
*/
|
|
186
|
+
declare function useCapabilities(): HostCapabilities | null;
|
|
187
|
+
/**
|
|
188
|
+
* Returns the input arguments passed to the tool that invoked this widget.
|
|
189
|
+
* Generic type parameter allows you to specify the expected input shape.
|
|
190
|
+
*
|
|
191
|
+
* @typeParam T - The expected shape of the tool input
|
|
192
|
+
* @returns Tool input object, or null if not yet received
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```tsx
|
|
196
|
+
* interface SearchInput {
|
|
197
|
+
* query: string;
|
|
198
|
+
* limit?: number;
|
|
199
|
+
* }
|
|
200
|
+
*
|
|
201
|
+
* function SearchWidget() {
|
|
202
|
+
* const input = useToolInput<SearchInput>();
|
|
203
|
+
*
|
|
204
|
+
* if (!input) return <div>Waiting for search query...</div>;
|
|
205
|
+
*
|
|
206
|
+
* return <SearchResults query={input.query} limit={input.limit ?? 10} />;
|
|
207
|
+
* }
|
|
208
|
+
* ```
|
|
209
|
+
*/
|
|
210
|
+
declare function useToolInput<T = Record<string, unknown>>(): T | null;
|
|
211
|
+
/**
|
|
212
|
+
* Returns partial tool input as it's being streamed (MCP only).
|
|
213
|
+
* Useful for showing real-time feedback as the user types.
|
|
214
|
+
*
|
|
215
|
+
* **Platform support:** MCP only. Returns null on ChatGPT.
|
|
216
|
+
*
|
|
217
|
+
* @typeParam T - The expected shape of the tool input
|
|
218
|
+
* @returns Partial tool input, or null
|
|
219
|
+
*
|
|
220
|
+
* @example
|
|
221
|
+
* ```tsx
|
|
222
|
+
* function StreamingInput() {
|
|
223
|
+
* const partial = useToolInputPartial<{ query: string }>();
|
|
224
|
+
* const final = useToolInput<{ query: string }>();
|
|
225
|
+
*
|
|
226
|
+
* // Show partial input with typing indicator
|
|
227
|
+
* if (partial && !final) {
|
|
228
|
+
* return <div className="opacity-50">{partial.query}...</div>;
|
|
229
|
+
* }
|
|
230
|
+
*
|
|
231
|
+
* return <div>{final?.query}</div>;
|
|
232
|
+
* }
|
|
233
|
+
* ```
|
|
234
|
+
*/
|
|
235
|
+
declare function useToolInputPartial<T = Record<string, unknown>>(): T | null;
|
|
236
|
+
/**
|
|
237
|
+
* Returns the result from a tool call made by the widget.
|
|
238
|
+
* Updates when tool calls complete.
|
|
239
|
+
*
|
|
240
|
+
* @returns Tool result object, or null if no result yet
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* ```tsx
|
|
244
|
+
* function ToolResultDisplay() {
|
|
245
|
+
* const result = useToolResult();
|
|
246
|
+
*
|
|
247
|
+
* if (!result) return null;
|
|
248
|
+
*
|
|
249
|
+
* if (result.isError) {
|
|
250
|
+
* return <div className="text-red-500">Error: {result.content?.[0]?.text}</div>;
|
|
251
|
+
* }
|
|
252
|
+
*
|
|
253
|
+
* return <div>{JSON.stringify(result.structuredContent)}</div>;
|
|
254
|
+
* }
|
|
255
|
+
* ```
|
|
256
|
+
*/
|
|
257
|
+
declare function useToolResult(): ToolResult | null;
|
|
258
|
+
/**
|
|
259
|
+
* Returns the current display mode and a function to request a mode change.
|
|
260
|
+
* Display mode controls how the widget is presented (inline, fullscreen, or pip).
|
|
261
|
+
*
|
|
262
|
+
* @returns Tuple of [currentMode, setMode]
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* ```tsx
|
|
266
|
+
* function ExpandableWidget() {
|
|
267
|
+
* const [mode, setMode] = useDisplayMode();
|
|
268
|
+
*
|
|
269
|
+
* return (
|
|
270
|
+
* <div>
|
|
271
|
+
* <p>Current mode: {mode}</p>
|
|
272
|
+
* {mode === 'inline' && (
|
|
273
|
+
* <button onClick={() => setMode('fullscreen')}>
|
|
274
|
+
* Expand to Fullscreen
|
|
275
|
+
* </button>
|
|
276
|
+
* )}
|
|
277
|
+
* {mode === 'fullscreen' && (
|
|
278
|
+
* <button onClick={() => setMode('inline')}>
|
|
279
|
+
* Collapse
|
|
280
|
+
* </button>
|
|
281
|
+
* )}
|
|
282
|
+
* </div>
|
|
283
|
+
* );
|
|
284
|
+
* }
|
|
285
|
+
* ```
|
|
286
|
+
*/
|
|
287
|
+
declare function useDisplayMode(): [
|
|
288
|
+
DisplayMode,
|
|
289
|
+
(mode: DisplayMode) => Promise<void>
|
|
290
|
+
];
|
|
291
|
+
/**
|
|
292
|
+
* Returns a function to call tools registered with the host.
|
|
293
|
+
* Tools allow your widget to perform actions and get data from the AI.
|
|
294
|
+
*
|
|
295
|
+
* @returns Async function to call tools
|
|
296
|
+
* @throws Error if bridge is not connected
|
|
297
|
+
*
|
|
298
|
+
* @example
|
|
299
|
+
* ```tsx
|
|
300
|
+
* function SearchWidget() {
|
|
301
|
+
* const callTool = useCallTool();
|
|
302
|
+
* const [results, setResults] = useState(null);
|
|
303
|
+
* const [loading, setLoading] = useState(false);
|
|
304
|
+
*
|
|
305
|
+
* const handleSearch = async (query: string) => {
|
|
306
|
+
* setLoading(true);
|
|
307
|
+
* try {
|
|
308
|
+
* const result = await callTool('search', { query, limit: 10 });
|
|
309
|
+
* if (result.isError) {
|
|
310
|
+
* console.error('Search failed');
|
|
311
|
+
* } else {
|
|
312
|
+
* setResults(result.structuredContent);
|
|
313
|
+
* }
|
|
314
|
+
* } finally {
|
|
315
|
+
* setLoading(false);
|
|
316
|
+
* }
|
|
317
|
+
* };
|
|
318
|
+
*
|
|
319
|
+
* return <SearchUI onSearch={handleSearch} results={results} loading={loading} />;
|
|
320
|
+
* }
|
|
321
|
+
* ```
|
|
322
|
+
*/
|
|
323
|
+
declare function useCallTool(): (name: string, args: Record<string, unknown>) => Promise<ToolResult>;
|
|
324
|
+
/**
|
|
325
|
+
* Returns a function to open links in the user's browser.
|
|
326
|
+
* This is the recommended way to open external URLs from your widget.
|
|
327
|
+
*
|
|
328
|
+
* @returns Async function to open links
|
|
329
|
+
* @throws Error if bridge is not connected
|
|
330
|
+
*
|
|
331
|
+
* @example
|
|
332
|
+
* ```tsx
|
|
333
|
+
* function LinkButton({ url, label }: { url: string; label: string }) {
|
|
334
|
+
* const openLink = useOpenLink();
|
|
335
|
+
*
|
|
336
|
+
* return (
|
|
337
|
+
* <button onClick={() => openLink(url)}>
|
|
338
|
+
* {label} ↗
|
|
339
|
+
* </button>
|
|
340
|
+
* );
|
|
341
|
+
* }
|
|
342
|
+
* ```
|
|
343
|
+
*/
|
|
344
|
+
declare function useOpenLink(): (url: string) => Promise<void>;
|
|
345
|
+
/**
|
|
346
|
+
* Returns a function to send a message to the conversation.
|
|
347
|
+
* Useful for suggesting follow-up prompts or triggering new interactions.
|
|
348
|
+
*
|
|
349
|
+
* @returns Async function to send messages
|
|
350
|
+
* @throws Error if bridge is not connected or sendMessage not supported
|
|
351
|
+
*
|
|
352
|
+
* @example
|
|
353
|
+
* ```tsx
|
|
354
|
+
* function SuggestionChips() {
|
|
355
|
+
* const sendMessage = useSendMessage();
|
|
356
|
+
*
|
|
357
|
+
* const suggestions = ['Tell me more', 'Show examples', 'Explain in detail'];
|
|
358
|
+
*
|
|
359
|
+
* return (
|
|
360
|
+
* <div className="flex gap-2">
|
|
361
|
+
* {suggestions.map(text => (
|
|
362
|
+
* <button key={text} onClick={() => sendMessage(text)}>
|
|
363
|
+
* {text}
|
|
364
|
+
* </button>
|
|
365
|
+
* ))}
|
|
366
|
+
* </div>
|
|
367
|
+
* );
|
|
368
|
+
* }
|
|
369
|
+
* ```
|
|
370
|
+
*/
|
|
371
|
+
declare function useSendMessage(): (text: string) => Promise<void>;
|
|
372
|
+
/**
|
|
373
|
+
* Returns a function to update the model's context (MCP only).
|
|
374
|
+
* Use this to provide additional context to the AI model.
|
|
375
|
+
*
|
|
376
|
+
* **Platform support:** MCP only. Logs a warning on ChatGPT.
|
|
377
|
+
*
|
|
378
|
+
* @returns Async function to update model context
|
|
379
|
+
*
|
|
380
|
+
* @example
|
|
381
|
+
* ```tsx
|
|
382
|
+
* function DataViewer({ data }: { data: object }) {
|
|
383
|
+
* const updateContext = useUpdateModelContext();
|
|
384
|
+
* const platform = usePlatform();
|
|
385
|
+
*
|
|
386
|
+
* useEffect(() => {
|
|
387
|
+
* if (platform === 'mcp') {
|
|
388
|
+
* updateContext({
|
|
389
|
+
* structuredContent: { currentData: data }
|
|
390
|
+
* });
|
|
391
|
+
* }
|
|
392
|
+
* }, [data, platform, updateContext]);
|
|
393
|
+
*
|
|
394
|
+
* return <pre>{JSON.stringify(data, null, 2)}</pre>;
|
|
395
|
+
* }
|
|
396
|
+
* ```
|
|
397
|
+
*/
|
|
398
|
+
declare function useUpdateModelContext(): (ctx: {
|
|
399
|
+
content?: ContentBlock[];
|
|
400
|
+
structuredContent?: Record<string, unknown>;
|
|
401
|
+
}) => Promise<void>;
|
|
402
|
+
/**
|
|
403
|
+
* Returns persisted widget state and a setter (ChatGPT only).
|
|
404
|
+
* State is preserved across page refreshes and conversation turns.
|
|
405
|
+
*
|
|
406
|
+
* **Platform support:** ChatGPT only. Logs a warning on MCP.
|
|
407
|
+
*
|
|
408
|
+
* @typeParam T - The shape of your widget state
|
|
409
|
+
* @returns Tuple of [state, setState]
|
|
410
|
+
*
|
|
411
|
+
* @example
|
|
412
|
+
* ```tsx
|
|
413
|
+
* interface MapState {
|
|
414
|
+
* center: { lat: number; lng: number };
|
|
415
|
+
* zoom: number;
|
|
416
|
+
* selectedMarker: string | null;
|
|
417
|
+
* }
|
|
418
|
+
*
|
|
419
|
+
* function MapWidget() {
|
|
420
|
+
* const [state, setState] = useWidgetState<MapState>();
|
|
421
|
+
*
|
|
422
|
+
* const handleZoom = (zoom: number) => {
|
|
423
|
+
* setState(prev => prev ? { ...prev, zoom } : { center: { lat: 0, lng: 0 }, zoom, selectedMarker: null });
|
|
424
|
+
* };
|
|
425
|
+
*
|
|
426
|
+
* return (
|
|
427
|
+
* <Map
|
|
428
|
+
* center={state?.center ?? { lat: 0, lng: 0 }}
|
|
429
|
+
* zoom={state?.zoom ?? 10}
|
|
430
|
+
* onZoomChange={handleZoom}
|
|
431
|
+
* />
|
|
432
|
+
* );
|
|
433
|
+
* }
|
|
434
|
+
* ```
|
|
435
|
+
*/
|
|
436
|
+
declare function useWidgetState<T = Record<string, unknown>>(): [
|
|
437
|
+
T | null,
|
|
438
|
+
(state: T | null) => void
|
|
439
|
+
];
|
|
440
|
+
/**
|
|
441
|
+
* Returns a function for structured logging (MCP only).
|
|
442
|
+
* Logs are sent to the MCP host for debugging and monitoring.
|
|
443
|
+
*
|
|
444
|
+
* **Platform support:** MCP only. Falls back to console.log on other platforms.
|
|
445
|
+
*
|
|
446
|
+
* @returns Log function that accepts level and message
|
|
447
|
+
*
|
|
448
|
+
* @example
|
|
449
|
+
* ```tsx
|
|
450
|
+
* function DataProcessor() {
|
|
451
|
+
* const log = useLog();
|
|
452
|
+
*
|
|
453
|
+
* const processData = async (data: unknown) => {
|
|
454
|
+
* log('info', 'Starting data processing');
|
|
455
|
+
* try {
|
|
456
|
+
* // Process data...
|
|
457
|
+
* log('debug', `Processed ${data.length} items`);
|
|
458
|
+
* } catch (error) {
|
|
459
|
+
* log('error', `Processing failed: ${error.message}`);
|
|
460
|
+
* }
|
|
461
|
+
* };
|
|
462
|
+
*
|
|
463
|
+
* return <button onClick={() => processData(someData)}>Process</button>;
|
|
464
|
+
* }
|
|
465
|
+
* ```
|
|
466
|
+
*/
|
|
467
|
+
declare function useLog(): (level: "debug" | "info" | "warning" | "error", data: string) => void;
|
|
468
|
+
/**
|
|
469
|
+
* Check if a specific feature is available on the current platform.
|
|
470
|
+
* This is a convenient wrapper around `useCapabilities()` for single feature checks.
|
|
471
|
+
*
|
|
472
|
+
* @param feature - The feature key to check
|
|
473
|
+
* @returns Whether the feature is available
|
|
474
|
+
*
|
|
475
|
+
* @example
|
|
476
|
+
* ```tsx
|
|
477
|
+
* function ConditionalFeatures() {
|
|
478
|
+
* const hasWidgetState = useFeature('widgetState');
|
|
479
|
+
* const hasModelContext = useFeature('modelContext');
|
|
480
|
+
*
|
|
481
|
+
* return (
|
|
482
|
+
* <div>
|
|
483
|
+
* {hasWidgetState && <StatePersistence />}
|
|
484
|
+
* {hasModelContext && <ContextUpdater />}
|
|
485
|
+
* </div>
|
|
486
|
+
* );
|
|
487
|
+
* }
|
|
488
|
+
* ```
|
|
489
|
+
*
|
|
490
|
+
* @example
|
|
491
|
+
* ```tsx
|
|
492
|
+
* // Combine with usePlatform for platform-specific UI
|
|
493
|
+
* function PlatformAwareWidget() {
|
|
494
|
+
* const platform = usePlatform();
|
|
495
|
+
* const hasFileUpload = useFeature('fileUpload');
|
|
496
|
+
*
|
|
497
|
+
* return (
|
|
498
|
+
* <div>
|
|
499
|
+
* <p>Running on: {platform}</p>
|
|
500
|
+
* {hasFileUpload ? <FileUploader /> : <p>File upload not available</p>}
|
|
501
|
+
* </div>
|
|
502
|
+
* );
|
|
503
|
+
* }
|
|
504
|
+
* ```
|
|
505
|
+
*/
|
|
506
|
+
declare function useFeature(feature: FeatureKey): boolean;
|
|
507
|
+
|
|
508
|
+
export { ContentBlock, type DetectionResult, DisplayMode, ExtendedBridge, FeatureKey, HostCapabilities, HostContext, Platform, ToolResult, UniversalProvider, type UniversalProviderProps, detectPlatform, detectPlatformDetailed, disableDebugMode, enableDebugMode, isChatGPT, isMCP, useCallTool, useCapabilities, useDisplayMode, useFeature, useHostContext, useLog, useOpenLink, usePlatform, useSendMessage, useTheme, useToolInput, useToolInputPartial, useToolResult, useUniversalBridge, useUpdateModelContext, useWidgetState };
|