jamdesk 1.1.178 → 1.1.180

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jamdesk",
3
- "version": "1.1.178",
3
+ "version": "1.1.180",
4
4
  "description": "CLI for Jamdesk — build, preview, and deploy documentation sites from MDX. Dev server with hot reload, 50+ components, OpenAPI support, AI search, and Mintlify migration",
5
5
  "keywords": [
6
6
  "jamdesk",
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { useState, useEffect, useRef, useCallback, useMemo } from 'react';
4
- import { ClaudeIcon, CursorIcon } from '@/components/mdx/ai-action-icons';
4
+ import { ChatGPTIcon, ClaudeIcon, CursorIcon, GeminiIcon, PerplexityIcon } from '@/components/mdx/ai-action-icons';
5
5
  import { useOnClickOutside } from '@/hooks/useOnClickOutside';
6
6
  import { usePathname } from 'next/navigation';
7
7
  import { AI_CHAT_URLS } from '@/lib/ai-service-urls';
@@ -109,31 +109,7 @@ function ExternalLinkIcon({ className }: { className?: string }) {
109
109
  );
110
110
  }
111
111
 
112
- // Brand logos
113
- function ChatGPTIcon({ className }: { className?: string }) {
114
- return (
115
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" className={className}>
116
- <path d="M22.282 9.821a5.985 5.985 0 0 0-.516-4.91 6.046 6.046 0 0 0-6.51-2.9A6.065 6.065 0 0 0 4.981 4.18a5.985 5.985 0 0 0-3.998 2.9 6.046 6.046 0 0 0 .743 7.097 5.98 5.98 0 0 0 .51 4.911 6.051 6.051 0 0 0 6.515 2.9A5.985 5.985 0 0 0 13.26 24a6.056 6.056 0 0 0 5.772-4.206 5.99 5.99 0 0 0 3.997-2.9 6.056 6.056 0 0 0-.747-7.073zM13.26 22.43a4.476 4.476 0 0 1-2.876-1.04l.141-.081 4.779-2.758a.795.795 0 0 0 .392-.681v-6.737l2.02 1.168a.071.071 0 0 1 .038.052v5.583a4.504 4.504 0 0 1-4.494 4.494zM3.6 18.304a4.47 4.47 0 0 1-.535-3.014l.142.085 4.783 2.759a.771.771 0 0 0 .78 0l5.843-3.369v2.332a.08.08 0 0 1-.033.062L9.74 19.95a4.5 4.5 0 0 1-6.14-1.646zM2.34 7.896a4.485 4.485 0 0 1 2.366-1.973V11.6a.766.766 0 0 0 .388.676l5.815 3.355-2.02 1.168a.076.076 0 0 1-.071 0l-4.83-2.786A4.504 4.504 0 0 1 2.34 7.872zm16.597 3.855l-5.833-3.387L15.119 7.2a.076.076 0 0 1 .071 0l4.83 2.791a4.494 4.494 0 0 1-.676 8.105v-5.678a.79.79 0 0 0-.407-.667zm2.01-3.023l-.141-.085-4.774-2.782a.776.776 0 0 0-.785 0L9.409 9.23V6.897a.066.066 0 0 1 .028-.061l4.83-2.787a4.5 4.5 0 0 1 6.68 4.66zm-12.64 4.135l-2.02-1.164a.08.08 0 0 1-.038-.057V6.075a4.5 4.5 0 0 1 7.375-3.453l-.142.08L8.704 5.46a.795.795 0 0 0-.393.681zm1.097-2.365l2.602-1.5 2.607 1.5v2.999l-2.597 1.5-2.607-1.5z" />
117
- </svg>
118
- );
119
- }
120
-
121
- function PerplexityIcon({ className }: { className?: string }) {
122
- return (
123
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 34 38" fill="currentColor" className={className}>
124
- <path fillRule="evenodd" clipRule="evenodd" d="M5.12114 0.0400391L15.919 9.98864V9.98636V0.062995H18.0209V10.0332L28.8671 0.0400391V11.3829H33.3202V27.744H28.8808V37.8442L18.0209 28.303V37.9538H15.919V28.4604L5.13338 37.96V27.744H0.680176V11.3829H5.12114V0.0400391ZM14.3344 13.4592H2.78208V25.6677H5.13074V21.8167L14.3344 13.4592ZM7.23518 22.7379V33.3271L15.919 25.6786V14.8506L7.23518 22.7379ZM18.0814 25.5775V14.8404L26.7677 22.7282V27.744H26.7789V33.219L18.0814 25.5775ZM28.8808 25.6677H31.2183V13.4592H19.752L28.8808 21.7302V25.6677ZM26.7652 11.3829V4.81584L19.6374 11.3829H26.7652ZM14.3507 11.3829H7.22306V4.81584L14.3507 11.3829Z" />
125
- </svg>
126
- );
127
- }
128
-
129
- function GeminiIcon({ className }: { className?: string }) {
130
- return (
131
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" className={className}>
132
- <path d="M11.04 19.32Q12 21.51 12 24q0-2.49.93-4.68.96-2.19 2.58-3.81t3.81-2.55Q21.51 12 24 12q-2.49 0-4.68-.93a12.3 12.3 0 0 1-3.81-2.58 12.3 12.3 0 0 1-2.58-3.81Q12 2.49 12 0q0 2.49-.96 4.68-.93 2.19-2.55 3.81a12.3 12.3 0 0 1-3.81 2.58Q2.49 12 0 12q2.49 0 4.68.96 2.19.93 3.81 2.55t2.55 3.81" />
133
- </svg>
134
- );
135
- }
136
-
112
+ // Brand logos (shared marks live in mdx/ai-action-icons.tsx)
137
113
  function VSCodeIcon({ className }: { className?: string }) {
138
114
  return (
139
115
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" fill="currentColor" className={className}>
@@ -17,11 +17,13 @@ import { useOnClickOutside } from '@/hooks/useOnClickOutside';
17
17
  import { renderInlineMarkdown } from '@/lib/inline-markdown';
18
18
  import { decodePromptSource } from '@/lib/prompt-source-codec';
19
19
 
20
- import { ClaudeIcon, CursorIcon } from './ai-action-icons';
20
+ import { ChatGPTIcon, ClaudeIcon, CursorIcon, GeminiIcon, PerplexityIcon } from './ai-action-icons';
21
+ import { useDocsLocale } from './docs-locale-context';
21
22
  import { Icon } from './Icon';
22
23
  import {
23
24
  resolvePromptActions,
24
25
  type PromptAction,
26
+ type PromptBuiltinAction,
25
27
  type ResolvedPromptAction,
26
28
  } from './prompt-actions';
27
29
 
@@ -55,17 +57,20 @@ function resolveAuthorIcon(icon: string | ReactElement, iconType?: IconType): st
55
57
  return `${iconType}/${icon}`;
56
58
  }
57
59
 
60
+ const BUILTIN_ACTION_ICONS: Record<Exclude<PromptBuiltinAction, 'copy'>, typeof ClaudeIcon> = {
61
+ cursor: CursorIcon,
62
+ claude: ClaudeIcon,
63
+ chatgpt: ChatGPTIcon,
64
+ perplexity: PerplexityIcon,
65
+ gemini: GeminiIcon,
66
+ };
67
+
58
68
  function ActionIcon({ action }: { action: ResolvedPromptAction['action'] }): ReactElement | null {
59
- if (action === 'cursor') {
60
- return <CursorIcon className="h-3.5 w-3.5 shrink-0" />;
61
- }
62
- if (action === 'claude') {
63
- return <ClaudeIcon className="h-3.5 w-3.5 shrink-0" />;
64
- }
65
- if (action === 'chatgpt') {
66
- return <Icon icon="brands/openai" size={14} className="shrink-0" />;
69
+ if (typeof action === 'string') {
70
+ const BrandIcon = BUILTIN_ACTION_ICONS[action];
71
+ return <BrandIcon className="h-3.5 w-3.5 shrink-0" />;
67
72
  }
68
- if (typeof action !== 'string' && action.icon) {
73
+ if (action.icon) {
69
74
  return <Icon icon={action.icon} size={14} className="shrink-0" />;
70
75
  }
71
76
  return null;
@@ -289,11 +294,12 @@ export function Prompt({
289
294
  const generatedMenuId = useId();
290
295
  const menuId = `prompt-actions-${generatedMenuId}`;
291
296
 
297
+ const locale = useDocsLocale();
292
298
  const prompt = useMemo(() => decodePromptSource(__promptSource), [__promptSource]);
293
299
  const hasPrompt = prompt.length > 0;
294
300
  const resolvedActions = useMemo(
295
- () => hasPrompt ? resolvePromptActions(actions, prompt) : [],
296
- [actions, hasPrompt, prompt],
301
+ () => hasPrompt ? resolvePromptActions(actions, prompt, locale) : [],
302
+ [actions, hasPrompt, locale, prompt],
297
303
  );
298
304
  const [primary, ...secondary] = resolvedActions;
299
305
 
@@ -1,3 +1,27 @@
1
+ export function ChatGPTIcon({ className }: { className?: string }) {
2
+ return (
3
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" className={className}>
4
+ <path d="M22.282 9.821a5.985 5.985 0 0 0-.516-4.91 6.046 6.046 0 0 0-6.51-2.9A6.065 6.065 0 0 0 4.981 4.18a5.985 5.985 0 0 0-3.998 2.9 6.046 6.046 0 0 0 .743 7.097 5.98 5.98 0 0 0 .51 4.911 6.051 6.051 0 0 0 6.515 2.9A5.985 5.985 0 0 0 13.26 24a6.056 6.056 0 0 0 5.772-4.206 5.99 5.99 0 0 0 3.997-2.9 6.056 6.056 0 0 0-.747-7.073zM13.26 22.43a4.476 4.476 0 0 1-2.876-1.04l.141-.081 4.779-2.758a.795.795 0 0 0 .392-.681v-6.737l2.02 1.168a.071.071 0 0 1 .038.052v5.583a4.504 4.504 0 0 1-4.494 4.494zM3.6 18.304a4.47 4.47 0 0 1-.535-3.014l.142.085 4.783 2.759a.771.771 0 0 0 .78 0l5.843-3.369v2.332a.08.08 0 0 1-.033.062L9.74 19.95a4.5 4.5 0 0 1-6.14-1.646zM2.34 7.896a4.485 4.485 0 0 1 2.366-1.973V11.6a.766.766 0 0 0 .388.676l5.815 3.355-2.02 1.168a.076.076 0 0 1-.071 0l-4.83-2.786A4.504 4.504 0 0 1 2.34 7.872zm16.597 3.855l-5.833-3.387L15.119 7.2a.076.076 0 0 1 .071 0l4.83 2.791a4.494 4.494 0 0 1-.676 8.105v-5.678a.79.79 0 0 0-.407-.667zm2.01-3.023l-.141-.085-4.774-2.782a.776.776 0 0 0-.785 0L9.409 9.23V6.897a.066.066 0 0 1 .028-.061l4.83-2.787a4.5 4.5 0 0 1 6.68 4.66zm-12.64 4.135l-2.02-1.164a.08.08 0 0 1-.038-.057V6.075a4.5 4.5 0 0 1 7.375-3.453l-.142.08L8.704 5.46a.795.795 0 0 0-.393.681zm1.097-2.365l2.602-1.5 2.607 1.5v2.999l-2.597 1.5-2.607-1.5z" />
5
+ </svg>
6
+ );
7
+ }
8
+
9
+ export function PerplexityIcon({ className }: { className?: string }) {
10
+ return (
11
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 34 38" fill="currentColor" className={className}>
12
+ <path fillRule="evenodd" clipRule="evenodd" d="M5.12114 0.0400391L15.919 9.98864V9.98636V0.062995H18.0209V10.0332L28.8671 0.0400391V11.3829H33.3202V27.744H28.8808V37.8442L18.0209 28.303V37.9538H15.919V28.4604L5.13338 37.96V27.744H0.680176V11.3829H5.12114V0.0400391ZM14.3344 13.4592H2.78208V25.6677H5.13074V21.8167L14.3344 13.4592ZM7.23518 22.7379V33.3271L15.919 25.6786V14.8506L7.23518 22.7379ZM18.0814 25.5775V14.8404L26.7677 22.7282V27.744H26.7789V33.219L18.0814 25.5775ZM28.8808 25.6677H31.2183V13.4592H19.752L28.8808 21.7302V25.6677ZM26.7652 11.3829V4.81584L19.6374 11.3829H26.7652ZM14.3507 11.3829H7.22306V4.81584L14.3507 11.3829Z" />
13
+ </svg>
14
+ );
15
+ }
16
+
17
+ export function GeminiIcon({ className }: { className?: string }) {
18
+ return (
19
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" className={className}>
20
+ <path d="M11.04 19.32Q12 21.51 12 24q0-2.49.93-4.68.96-2.19 2.58-3.81t3.81-2.55Q21.51 12 24 12q-2.49 0-4.68-.93a12.3 12.3 0 0 1-3.81-2.58 12.3 12.3 0 0 1-2.58-3.81Q12 2.49 12 0q0 2.49-.96 4.68-.93 2.19-2.55 3.81a12.3 12.3 0 0 1-3.81 2.58Q2.49 12 0 12q2.49 0 4.68.96 2.19.93 3.81 2.55t2.55 3.81" />
21
+ </svg>
22
+ );
23
+ }
24
+
1
25
  export function CursorIcon({ className }: { className?: string }) {
2
26
  return (
3
27
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" className={className}>
@@ -0,0 +1,31 @@
1
+ 'use client';
2
+
3
+ import { createContext, useContext, type ReactNode } from 'react';
4
+
5
+ /**
6
+ * The rendered page's language code, whitelisted against the project's
7
+ * `navigation.languages` (see resolveLocaleFromPath in lib/language-utils.ts —
8
+ * a path segment that merely looks like a language code never counts).
9
+ *
10
+ * Empty string = default/unknown locale; consumers fall back to English.
11
+ * Surfaces without the provider (dashboard editor preview) get the default.
12
+ */
13
+ const DocsLocaleContext = createContext<string>('');
14
+
15
+ export function DocsLocaleProvider({
16
+ children,
17
+ locale,
18
+ }: {
19
+ children: ReactNode;
20
+ locale: string;
21
+ }): React.ReactElement {
22
+ return (
23
+ <DocsLocaleContext.Provider value={locale}>
24
+ {children}
25
+ </DocsLocaleContext.Provider>
26
+ );
27
+ }
28
+
29
+ export function useDocsLocale(): string {
30
+ return useContext(DocsLocaleContext);
31
+ }
@@ -1,6 +1,6 @@
1
1
  import { AI_CHAT_URLS } from '@/lib/ai-service-urls';
2
2
 
3
- export type PromptBuiltinAction = 'copy' | 'cursor' | 'claude' | 'chatgpt';
3
+ export type PromptBuiltinAction = 'copy' | 'cursor' | 'claude' | 'chatgpt' | 'perplexity' | 'gemini';
4
4
 
5
5
  export interface PromptCustomAction {
6
6
  label: string;
@@ -17,6 +17,8 @@ const BASES: Record<Exclude<PromptBuiltinAction, 'copy'>, string> = {
17
17
  cursor: AI_CHAT_URLS.cursor,
18
18
  claude: AI_CHAT_URLS.claude,
19
19
  chatgpt: AI_CHAT_URLS.chatgpt,
20
+ perplexity: AI_CHAT_URLS.perplexity,
21
+ gemini: AI_CHAT_URLS.gemini,
20
22
  };
21
23
 
22
24
  export function normalizePromptActions(actions: unknown): PromptOpenAction[] {
@@ -38,7 +40,7 @@ function normalizePromptActionsUnsafe(actions: unknown): PromptOpenAction[] {
38
40
  if (action === 'copy') continue;
39
41
 
40
42
  if (typeof action === 'string') {
41
- if (!['cursor', 'claude', 'chatgpt'].includes(action) || seen.has(action)) continue;
43
+ if (!['cursor', 'claude', 'chatgpt', 'perplexity', 'gemini'].includes(action) || seen.has(action)) continue;
42
44
  seen.add(action);
43
45
  normalized.push(action as Exclude<PromptBuiltinAction, 'copy'>);
44
46
  continue;
@@ -117,13 +119,47 @@ export interface ResolvedPromptAction {
117
119
  label: string;
118
120
  }
119
121
 
120
- const BUILTIN_META = {
121
- cursor: { label: 'Open in Cursor' },
122
- claude: { label: 'Open in Claude' },
123
- chatgpt: { label: 'Open in ChatGPT' },
124
- } as const;
122
+ const BUILTIN_TOOL_NAMES: Record<Exclude<PromptBuiltinAction, 'copy'>, string> = {
123
+ cursor: 'Cursor',
124
+ claude: 'Claude',
125
+ chatgpt: 'ChatGPT',
126
+ perplexity: 'Perplexity',
127
+ gemini: 'Gemini',
128
+ };
129
+
130
+ // "Open in {tool}" per page language. Keys are lowercased language codes;
131
+ // regional variants fall back to the base language, unknown locales to English.
132
+ const OPEN_IN_TEMPLATES: Record<string, (tool: string) => string> = {
133
+ en: (tool) => `Open in ${tool}`,
134
+ fr: (tool) => `Ouvrir dans ${tool}`,
135
+ es: (tool) => `Abrir en ${tool}`,
136
+ de: (tool) => `In ${tool} öffnen`,
137
+ it: (tool) => `Apri in ${tool}`,
138
+ pt: (tool) => `Abrir no ${tool}`,
139
+ nl: (tool) => `Openen in ${tool}`,
140
+ ja: (tool) => `${tool}で開く`,
141
+ ko: (tool) => `${tool}에서 열기`,
142
+ zh: (tool) => `在 ${tool} 中打开`,
143
+ 'zh-tw': (tool) => `在 ${tool} 中開啟`,
144
+ 'zh-hk': (tool) => `在 ${tool} 中開啟`,
145
+ };
146
+
147
+ export function getBuiltinActionLabel(
148
+ action: Exclude<PromptBuiltinAction, 'copy'>,
149
+ locale = '',
150
+ ): string {
151
+ const lowered = locale.toLowerCase();
152
+ const template = OPEN_IN_TEMPLATES[lowered]
153
+ ?? OPEN_IN_TEMPLATES[lowered.split('-')[0]]
154
+ ?? OPEN_IN_TEMPLATES.en;
155
+ return template(BUILTIN_TOOL_NAMES[action]);
156
+ }
125
157
 
126
- export function resolvePromptActions(actions: unknown, prompt: string): ResolvedPromptAction[] {
158
+ export function resolvePromptActions(
159
+ actions: unknown,
160
+ prompt: string,
161
+ locale = '',
162
+ ): ResolvedPromptAction[] {
127
163
  return normalizePromptActions(actions).flatMap((action) => {
128
164
  const href = buildPromptActionUrl(action, prompt);
129
165
  if (!href) return [];
@@ -131,7 +167,7 @@ export function resolvePromptActions(actions: unknown, prompt: string): Resolved
131
167
  return [{
132
168
  action,
133
169
  href,
134
- label: typeof action === 'string' ? BUILTIN_META[action].label : action.label,
170
+ label: typeof action === 'string' ? getBuiltinActionLabel(action, locale) : action.label,
135
171
  }];
136
172
  });
137
173
  }
@@ -86,7 +86,8 @@ import {
86
86
  } from '@/lib/openapi';
87
87
  import { classifyOpenApiLoadError } from '@/lib/openapi/classify-load-error';
88
88
  import { findOperation, deriveOperationDescription, collectLocalSpecPaths } from '@/lib/openapi/operation-description';
89
- import { extractLanguageFromPath, isValidLanguageCode } from '@/lib/language-utils';
89
+ import { extractLanguageFromPath, isValidLanguageCode, resolveLocaleFromPath } from '@/lib/language-utils';
90
+ import { DocsLocaleProvider } from '@/components/mdx/docs-locale-context';
90
91
  import { findFirstNavPage } from '@/lib/find-first-nav-page';
91
92
  import { candidateSpecPaths } from '@/lib/openapi/lang-spec-path';
92
93
  import { ApiEndpoint } from '@/components/mdx/ApiEndpoint';
@@ -419,6 +420,14 @@ export async function renderDocPage(input: RenderInput): Promise<ReactElement> {
419
420
  const data = parsed.data as FrontmatterData;
420
421
  const rawContent = parsed.content;
421
422
 
423
+ // Whitelisted page locale for localized component chrome (Prompt action
424
+ // labels). Unlike `currentLang` above, this only counts a path prefix that
425
+ // is actually declared in navigation.languages — '' otherwise.
426
+ const docsLocale = resolveLocaleFromPath(
427
+ `/${pagePath}`,
428
+ config.navigation?.languages?.map((l) => l.language) ?? [],
429
+ );
430
+
422
431
  const baseUrl = resolveBaseUrl(requestHeaders, projectSlug, hostAtDocs);
423
432
  const faqPairs = extractFaqPairs(rawContent);
424
433
  const ogImageUrl = buildPageOgImageUrl(config, data, baseUrl);
@@ -853,21 +862,23 @@ export async function renderDocPage(input: RenderInput): Promise<ReactElement> {
853
862
  <MdxErrorBlock label="page content" />
854
863
  ) : (
855
864
  <MdxRenderBoundary fallback={<MdxErrorBlock label="page content" />}>
856
- <StepSlugProvider entries={stepEntries}>
857
- <UpdateSlugProvider entries={updateEntries}>
858
- <MDXRemote
859
- source={effectiveSource}
860
- components={ComponentsWithUnknownFallback}
861
- options={{
862
- ...mdxSecurityOptions,
863
- mdxOptions: {
864
- ...getCommonMdxOptions(config, highlighter),
865
- recmaPlugins: [recmaCompoundComponents, recmaGuardExpressions],
866
- },
867
- }}
868
- />
869
- </UpdateSlugProvider>
870
- </StepSlugProvider>
865
+ <DocsLocaleProvider locale={docsLocale}>
866
+ <StepSlugProvider entries={stepEntries}>
867
+ <UpdateSlugProvider entries={updateEntries}>
868
+ <MDXRemote
869
+ source={effectiveSource}
870
+ components={ComponentsWithUnknownFallback}
871
+ options={{
872
+ ...mdxSecurityOptions,
873
+ mdxOptions: {
874
+ ...getCommonMdxOptions(config, highlighter),
875
+ recmaPlugins: [recmaCompoundComponents, recmaGuardExpressions],
876
+ },
877
+ }}
878
+ />
879
+ </UpdateSlugProvider>
880
+ </StepSlugProvider>
881
+ </DocsLocaleProvider>
871
882
  </MdxRenderBoundary>
872
883
  )}
873
884
  </div>
@@ -885,21 +896,23 @@ export async function renderDocPage(input: RenderInput): Promise<ReactElement> {
885
896
  <MdxErrorBlock label="page content" />
886
897
  ) : (
887
898
  <MdxRenderBoundary fallback={<MdxErrorBlock label="page content" />}>
888
- <StepSlugProvider entries={stepEntries}>
889
- <UpdateSlugProvider entries={updateEntries}>
890
- <MDXRemote
891
- source={content}
892
- components={ComponentsWithUnknownFallback}
893
- options={{
894
- ...mdxSecurityOptions,
895
- mdxOptions: {
896
- ...getCommonMdxOptions(config, highlighter),
897
- recmaPlugins: [recmaCompoundComponents, recmaGuardExpressions],
898
- },
899
- }}
900
- />
901
- </UpdateSlugProvider>
902
- </StepSlugProvider>
899
+ <DocsLocaleProvider locale={docsLocale}>
900
+ <StepSlugProvider entries={stepEntries}>
901
+ <UpdateSlugProvider entries={updateEntries}>
902
+ <MDXRemote
903
+ source={content}
904
+ components={ComponentsWithUnknownFallback}
905
+ options={{
906
+ ...mdxSecurityOptions,
907
+ mdxOptions: {
908
+ ...getCommonMdxOptions(config, highlighter),
909
+ recmaPlugins: [recmaCompoundComponents, recmaGuardExpressions],
910
+ },
911
+ }}
912
+ />
913
+ </UpdateSlugProvider>
914
+ </StepSlugProvider>
915
+ </DocsLocaleProvider>
903
916
  </MdxRenderBoundary>
904
917
  );
905
918