jamdesk 1.1.141 → 1.1.142

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.
@@ -26,6 +26,7 @@ export interface DeprecatedComponentInfo {
26
26
  /**
27
27
  * Map of deprecated components to their replacements.
28
28
  * Add new deprecated components here as they are removed.
29
+ * NEVER remove entries: render-time auto-migrate (preprocess-mdx.ts) rewrites stale R2 content with them forever.
29
30
  */
30
31
  export declare const DEPRECATED_COMPONENTS: Record<string, DeprecatedComponentInfo>;
31
32
  export interface DeprecatedComponentError {
@@ -1 +1 @@
1
- {"version":3,"file":"deprecated-components.d.ts","sourceRoot":"","sources":["../../src/lib/deprecated-components.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CACjD;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAkBzE,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,wBAAwB,EAAE,CAsB5B;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,wBAAwB,GAAG;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB,CAQA;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,wBAAwB,EAAE,GAAG;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB,CAqCA;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CA0BnG"}
1
+ {"version":3,"file":"deprecated-components.d.ts","sourceRoot":"","sources":["../../src/lib/deprecated-components.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CACjD;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAkBzE,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,wBAAwB,EAAE,CAsB5B;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,wBAAwB,GAAG;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB,CAQA;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,wBAAwB,EAAE,GAAG;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB,CAqCA;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CA0BnG"}
@@ -15,6 +15,7 @@
15
15
  /**
16
16
  * Map of deprecated components to their replacements.
17
17
  * Add new deprecated components here as they are removed.
18
+ * NEVER remove entries: render-time auto-migrate (preprocess-mdx.ts) rewrites stale R2 content with them forever.
18
19
  */
19
20
  export const DEPRECATED_COMPONENTS = {
20
21
  CardGroup: {
@@ -1 +1 @@
1
- {"version":3,"file":"deprecated-components.js","sourceRoot":"","sources":["../../src/lib/deprecated-components.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"deprecated-components.js","sourceRoot":"","sources":["../../src/lib/deprecated-components.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jamdesk",
3
- "version": "1.1.141",
3
+ "version": "1.1.142",
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,16 +1,34 @@
1
1
  'use client';
2
2
 
3
3
  import { memo } from 'react';
4
+ import { useRouter } from 'next/navigation';
4
5
  import ReactMarkdown from 'react-markdown';
5
6
  import remarkGfm from 'remark-gfm';
7
+ import { slug as githubSlug } from 'github-slugger';
6
8
  import { ChatCodeBlock } from './ChatCodeBlock';
7
9
  import { CopyButton } from './CopyButton';
10
+ import { isModifiedClick } from '@/lib/is-modified-click';
8
11
  import { useLinkPrefix } from '@/lib/link-prefix-context';
9
12
  import type { ChatMessage as ChatMessageType } from '@/hooks/useChat';
10
13
 
11
- /** Convert heading text to a URL-friendly slug (same as heading-extractor.ts). */
12
- function slugify(text: string): string {
13
- return text.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
14
+ /**
15
+ * Local path (pathname + query + hash) when href points at this docs site,
16
+ * null when it's genuinely external. The server rewrites doc links to
17
+ * canonical ABSOLUTE URLs on the host the user is browsing (link-rewriter.ts
18
+ * builds them from the forwarded host), so "starts with http" cannot
19
+ * distinguish doc links from external ones — only an origin comparison can.
20
+ * Safe to read window here: ChatPanel is loaded with ssr:false, so this never
21
+ * runs on the server (and the try/catch covers any non-DOM environment).
22
+ */
23
+ function localPathIfSameSite(href: string): string | null {
24
+ try {
25
+ const url = new URL(href, window.location.href);
26
+ return url.origin === window.location.origin
27
+ ? `${url.pathname}${url.search}${url.hash}`
28
+ : null;
29
+ } catch {
30
+ return null;
31
+ }
14
32
  }
15
33
 
16
34
  interface ChatMessageProps {
@@ -41,7 +59,16 @@ function stripOptionList(content: string): string {
41
59
  * but without memo every message in the list would re-render.
42
60
  */
43
61
  export const ChatMessage = memo(function ChatMessage({ message, onSelectOption }: ChatMessageProps) {
62
+ const router = useRouter();
44
63
  const linkPrefix = useLinkPrefix();
64
+
65
+ // Same-site links navigate client-side so the chat panel (state in the
66
+ // root layout) stays open. Modified/middle clicks keep native behavior.
67
+ const navigateInPage = (e: React.MouseEvent<HTMLAnchorElement>, path: string) => {
68
+ if (isModifiedClick(e)) return;
69
+ e.preventDefault();
70
+ router.push(path);
71
+ };
45
72
  const isUser = message.role === 'user';
46
73
  const hasClarificationOptions = !isUser && !!message.clarificationOptions?.length && !message.isStreaming;
47
74
  const clarificationDisabled = !!message.clarificationSelected;
@@ -106,11 +133,13 @@ export const ChatMessage = memo(function ChatMessage({ message, onSelectOption }
106
133
  );
107
134
  },
108
135
  a: ({ href, children }) => {
109
- const isExternal = href?.startsWith('http');
136
+ const localPath = href ? localPathIfSameSite(href) : null;
110
137
  return (
111
138
  <a
112
139
  href={href}
113
- {...(isExternal ? { target: '_blank', rel: 'noopener noreferrer' } : {})}
140
+ onClick={localPath ? (e) => navigateInPage(e, localPath) : undefined}
141
+ target={localPath ? undefined : '_blank'}
142
+ rel={localPath ? undefined : 'noopener noreferrer'}
114
143
  >
115
144
  {children}
116
145
  </a>
@@ -164,16 +193,21 @@ export const ChatMessage = memo(function ChatMessage({ message, onSelectOption }
164
193
  <div className="mt-4 pt-4 border-t border-[var(--color-border)]">
165
194
  <p className="text-[11px] font-medium text-[var(--color-text-muted)] mb-1.5">Related docs</p>
166
195
  <div className="flex flex-wrap gap-1.5">
167
- {message.citations.map((citation) => (
168
- <a
169
- key={citation.slug}
170
- href={`${linkPrefix}/${citation.slug}${citation.section ? `#${slugify(citation.section)}` : ''}`}
171
- className="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-lg border border-[var(--color-border)] bg-[var(--color-bg-secondary)] text-xs text-[var(--color-text-secondary)] hover:border-[var(--color-accent)] hover:text-[var(--color-accent)] transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--color-accent)]"
172
- >
173
- <i className="fa-solid fa-file-lines text-[10px]" aria-hidden="true" />
174
- {citation.title}
175
- </a>
176
- ))}
196
+ {message.citations.map((citation) => {
197
+ // github-slugger matches the ids rehype-slug assigns to headings
198
+ const citationHref = `${linkPrefix}/${citation.slug}${citation.section ? `#${githubSlug(citation.section)}` : ''}`;
199
+ return (
200
+ <a
201
+ key={citation.slug}
202
+ href={citationHref}
203
+ onClick={(e) => navigateInPage(e, citationHref)}
204
+ className="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-lg border border-[var(--color-border)] bg-[var(--color-bg-secondary)] text-xs text-[var(--color-text-secondary)] hover:border-[var(--color-accent)] hover:text-[var(--color-accent)] transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--color-accent)]"
205
+ >
206
+ <i className="fa-solid fa-file-lines text-[10px]" aria-hidden="true" />
207
+ {citation.title}
208
+ </a>
209
+ );
210
+ })}
177
211
  </div>
178
212
  </div>
179
213
  )}
@@ -1,6 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import type { ReactNode } from 'react';
4
+ import { isModifiedClick } from '@/lib/is-modified-click';
4
5
 
5
6
  /**
6
7
  * In embed mode the page lives inside a cross-origin iframe (the widget modal).
@@ -12,10 +13,7 @@ import type { ReactNode } from 'react';
12
13
  */
13
14
  export function EmbedLinkInterceptor({ children }: { children: ReactNode }) {
14
15
  const onClick = (e: React.MouseEvent<HTMLDivElement>) => {
15
- // Defer entirely to the browser for modified / non-primary clicks: the user
16
- // has already asked for new-tab (cmd/ctrl), new-window (shift) or background
17
- // (middle) behavior — hijacking it would double-open or break their intent.
18
- if (e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
16
+ if (isModifiedClick(e)) return;
19
17
  const anchor = (e.target as HTMLElement).closest('a');
20
18
  if (!anchor) return;
21
19
  const href = anchor.getAttribute('href');
@@ -157,6 +157,7 @@ export function SearchModal({ isOpen, onClose, popularPages, onNavigate }: Searc
157
157
  const router = useRouter();
158
158
  const resultsContainerRef = useRef<HTMLDivElement>(null);
159
159
  const modalRef = useRef<HTMLDivElement>(null);
160
+ const inputRef = useRef<HTMLInputElement>(null);
160
161
  // Track if user clicked a result (to avoid double-tracking on modal close)
161
162
  const hasTrackedRef = useRef(false);
162
163
  // Store last search state for tracking on modal close
@@ -519,17 +520,34 @@ export function SearchModal({ isOpen, onClose, popularPages, onNavigate }: Searc
519
520
  <div className="flex items-center gap-3 px-4 py-3 border-b border-[var(--color-border)]">
520
521
  <i className="fa-solid fa-magnifying-glass h-4 w-4 text-[var(--color-text-muted)] flex-shrink-0" aria-hidden="true" />
521
522
  <input
523
+ ref={inputRef}
522
524
  type="search"
523
525
  placeholder="Search documentation…"
524
526
  value={query}
525
527
  onChange={(e) => setQuery(e.target.value)}
526
- className="flex-1 bg-transparent text-[var(--color-text-primary)] placeholder-[var(--color-text-muted)] outline-none text-base"
528
+ className="flex-1 bg-transparent text-[var(--color-text-primary)] placeholder-[var(--color-text-muted)] outline-none text-base [&::-webkit-search-cancel-button]:appearance-none [&::-webkit-search-decoration]:appearance-none"
527
529
  autoComplete="off"
528
530
  autoFocus
529
531
  aria-label="Search documentation"
530
532
  aria-controls="search-results"
531
533
  aria-activedescendant={rows[selectedIndex] ? `search-result-${selectedIndex}` : undefined}
532
534
  />
535
+ {query && (
536
+ <button
537
+ type="button"
538
+ onClick={() => {
539
+ setQuery('');
540
+ inputRef.current?.focus();
541
+ }}
542
+ className="flex items-center justify-center w-4 h-4 cursor-pointer rounded-full bg-[var(--color-text-muted)] hover:bg-[var(--color-text-secondary)] transition-colors flex-shrink-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--color-accent)]"
543
+ aria-label="Clear search"
544
+ >
545
+ <i
546
+ className="fa-solid fa-xmark text-[9px] leading-none text-[var(--color-bg-primary)]"
547
+ aria-hidden="true"
548
+ />
549
+ </button>
550
+ )}
533
551
  <button
534
552
  onClick={onClose}
535
553
  className="p-1.5 cursor-pointer hover:bg-[var(--color-bg-tertiary)] rounded-lg transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--color-accent)]"
@@ -24,6 +24,7 @@ export interface DeprecatedComponentInfo {
24
24
  /**
25
25
  * Map of deprecated components to their replacements.
26
26
  * Add new deprecated components here as they are removed.
27
+ * NEVER remove entries: render-time auto-migrate (preprocess-mdx.ts) rewrites stale R2 content with them forever.
27
28
  */
28
29
  export const DEPRECATED_COMPONENTS: Record<string, DeprecatedComponentInfo> = {
29
30
  CardGroup: {
@@ -0,0 +1,20 @@
1
+ import admin from 'firebase-admin';
2
+
3
+ /**
4
+ * True when a Firestore project claims this slug (the canonical slug lives at
5
+ * projects/{id}/github/config.slug — collection-group query avoids enumerating
6
+ * every project). Used as the server-side guard for expectOrphan deletes:
7
+ * orphan-purge tooling must never be able to wipe a live tenant, regardless of
8
+ * what a client-side script computed. The collection-group single-field index
9
+ * exemption for `github.slug` (COLLECTION_GROUP ASCENDING) already exists in
10
+ * dashboard/firestore.indexes.json, so this query needs no new index.
11
+ */
12
+ export async function isSlugActive(slug: string): Promise<boolean> {
13
+ const snap = await admin
14
+ .firestore()
15
+ .collectionGroup('github')
16
+ .where('slug', '==', slug)
17
+ .limit(1)
18
+ .get();
19
+ return !snap.empty;
20
+ }
@@ -0,0 +1,11 @@
1
+ import type { MouseEvent } from 'react';
2
+
3
+ /**
4
+ * True when the user has asked the browser for special handling — new tab
5
+ * (cmd/ctrl), new window (shift), background tab (middle/non-primary button) —
6
+ * or another handler already claimed the event. Click interceptors must defer
7
+ * to native behavior in these cases instead of hijacking the click.
8
+ */
9
+ export function isModifiedClick(e: MouseEvent): boolean {
10
+ return e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey;
11
+ }
@@ -431,6 +431,10 @@ const SKIP_EXTENSIONS = [
431
431
  '.ttf',
432
432
  '.eot',
433
433
  '.map',
434
+ // sitemap.xsl is constant content (no project context needed); skipping
435
+ // avoids the resolution round-trip AND the password gate, which special-
436
+ // cases sitemap.xml but would otherwise intercept the stylesheet fetch.
437
+ '.xsl',
434
438
  ];
435
439
 
436
440
  /**
@@ -7,8 +7,9 @@
7
7
  */
8
8
 
9
9
  import { ASSET_PREFIX, appendAssetVersion } from './docs-types';
10
- import { checkForDeprecatedComponents } from './deprecated-components';
10
+ import { convertDeprecatedComponents } from './deprecated-components';
11
11
  import { filterVisibility } from './visibility-filter';
12
+ import { logger } from '../shared/logger';
12
13
 
13
14
  /**
14
15
  * JSX components that contain markdown content requiring special preprocessing.
@@ -1083,6 +1084,24 @@ export function preprocessMdx(content: string, options?: { assetVersion?: string
1083
1084
  // that flow through preprocessMdx independently.
1084
1085
  processed = filterVisibility(processed, 'humans');
1085
1086
 
1087
+ // Auto-migrate deprecated components instead of failing. Builds hard-fail
1088
+ // on these separately (build.ts — now the SOLE author-facing gate) so
1089
+ // authors are still told — but content uploaded to R2 BEFORE a component
1090
+ // was deprecated never rebuilds, and throwing here turned every render of
1091
+ // such a page into a 500 (2026-06-12 mintlfiy incident). Render what the
1092
+ // author meant. Runs EARLY so converted tags (e.g. <Columns>) get the same
1093
+ // JSX_CONTENT_COMPONENTS indentation/blank-line treatment as authored ones.
1094
+ // Called unconditionally so self-closing forms (e.g. <CardGroup/>) are not
1095
+ // silently skipped — conversion gates on changes.length > 0, not on a
1096
+ // separate pre-check whose pattern was narrower than convertDeprecatedComponents.
1097
+ const { content: converted, changes } = convertDeprecatedComponents(processed);
1098
+ if (changes.length > 0) {
1099
+ processed = converted;
1100
+ logger.warn(
1101
+ `[MDX] auto-migrated deprecated component(s) at render time: ${changes.join('; ')} — run \`jamdesk migrate\` to update the source`,
1102
+ );
1103
+ }
1104
+
1086
1105
  // Strip snippet imports
1087
1106
  processed = stripSnippetImports(processed);
1088
1107
 
@@ -1136,17 +1155,6 @@ export function preprocessMdx(content: string, options?: { assetVersion?: string
1136
1155
  // it and bleed an :HL hint into prefetched RSC payloads.
1137
1156
  processed = addLazyLoadingToRawImg(processed);
1138
1157
 
1139
- // Check for deprecated components (defense-in-depth - builds also check earlier)
1140
- const deprecatedErrors = checkForDeprecatedComponents(processed, 'content');
1141
- if (deprecatedErrors.length > 0) {
1142
- const err = deprecatedErrors[0];
1143
- throw new Error(
1144
- `<${err.component}> has been removed. Use <${err.replacement}> instead.\n\n` +
1145
- `${err.migrationHint}\n\n` +
1146
- `Run \`jamdesk migrate\` to convert automatically.`
1147
- );
1148
- }
1149
-
1150
1158
  // Clean up any resulting empty lines at the start
1151
1159
  processed = processed.replace(/^\n+/, '');
1152
1160
 
@@ -116,6 +116,38 @@ export async function deleteDomainAuthSecret(
116
116
  await upstashCommand(kvUrl, kvToken, 'DEL', `domainAuthSecret:${hostname}`);
117
117
  }
118
118
 
119
+ /**
120
+ * Purge ALL slug-scoped Redis keys for a deleted project.
121
+ *
122
+ * Project deletion historically removed only the domain-scoped keys
123
+ * (domain:/domainCfg:/domainVerify:/domainStatus:, via removeDomain) and left
124
+ * these six behind — which kept deleted tenants resolvable on *.jamdesk.app
125
+ * and serving stale R2 content (2026-06-12 mintlfiy incident). Called from
126
+ * the build-service /delete-project-assets handler during the delete cascade.
127
+ *
128
+ * Returns the number of keys that actually existed and were deleted.
129
+ */
130
+ export async function purgeProjectRedisKeys(
131
+ slug: string,
132
+ kvUrl?: string,
133
+ kvToken?: string
134
+ ): Promise<number> {
135
+ if (!kvUrl || !kvToken) return 0;
136
+ const keys = [
137
+ `projectCfg:${slug}`,
138
+ `projectInactive:${slug}`,
139
+ `projectMeta:${slug}`,
140
+ `projectAuthSecret:${slug}`,
141
+ `projectAuthPublic:${slug}`,
142
+ `domainAuthSecret:${slug}.jamdesk.app`,
143
+ ];
144
+ // Single variadic DEL: one round trip, and atomic on the Redis side — a
145
+ // transient failure can't purge some keys and orphan the rest (the exact
146
+ // partial-purge incident class this function exists to close).
147
+ const result = await upstashCommand(kvUrl, kvToken, 'DEL', ...keys);
148
+ return typeof result === 'number' ? result : 0;
149
+ }
150
+
119
151
  // ---------------------------------------------------------------------------
120
152
  // Project inactive flag — write side only.
121
153
  // Set when the project owner's subscription is canceled, past_due, or
@@ -338,7 +338,17 @@ export async function renderDocPage(input: RenderInput): Promise<ReactElement> {
338
338
  ? import('@/lib/openapi-isr')
339
339
  : null;
340
340
 
341
- const content = preprocessMdx(rawContent, { assetVersion: config.assetVersion });
341
+ // Preprocess can throw on malformed stale R2 content. A throw here escapes
342
+ // every guard below and 500s via error.tsx — catch it and route to the same
343
+ // inline-placeholder path as a compile failure (never-500 invariant).
344
+ let content = '';
345
+ let preprocessError: string | null = null;
346
+ try {
347
+ content = preprocessMdx(rawContent, { assetVersion: config.assetVersion });
348
+ } catch (err) {
349
+ preprocessError = err instanceof Error ? err.message : String(err);
350
+ logger.warn(`[MDX] preprocess failed for ${pagePath}: ${preprocessError}`);
351
+ }
342
352
 
343
353
  const stepEntries: StepSlugEntry[] = extractHeadings(content)
344
354
  .filter(h => typeof h.stepNumber === 'number')
@@ -487,31 +497,33 @@ export async function renderDocPage(input: RenderInput): Promise<ReactElement> {
487
497
  ? content.replace(/<ResponseExample>[\s\S]*?<\/ResponseExample>/g, '')
488
498
  : content;
489
499
  const missingRefCollector: MissingRefCollector = { names: [] };
490
- let mdxError: string | null = null;
500
+ let mdxError: string | null = preprocessError;
491
501
  let mdxCompileMs: number | null = null;
492
502
  const mdxCompileStart = performance.now();
493
- try {
494
- await compileMDX({
495
- source: effectiveSource,
496
- components: AllComponentsWithInline,
497
- options: {
498
- ...mdxSecurityOptions,
499
- mdxOptions: {
500
- ...getCommonMdxOptions(config, highlighter),
501
- recmaPlugins: [
502
- recmaCompoundComponents,
503
- recmaCollectMissingRefs(missingRefCollector),
504
- recmaGuardExpressions,
505
- ],
503
+ if (!mdxError) {
504
+ try {
505
+ await compileMDX({
506
+ source: effectiveSource,
507
+ components: AllComponentsWithInline,
508
+ options: {
509
+ ...mdxSecurityOptions,
510
+ mdxOptions: {
511
+ ...getCommonMdxOptions(config, highlighter),
512
+ recmaPlugins: [
513
+ recmaCompoundComponents,
514
+ recmaCollectMissingRefs(missingRefCollector),
515
+ recmaGuardExpressions,
516
+ ],
517
+ },
506
518
  },
507
- },
508
- });
509
- } catch (err) {
510
- // Syntax/compile failure the only path that can 500 around MDXRemote.
511
- // Degrade to an inline placeholder; the chosen branch renders it instead
512
- // of calling MDXRemote with source known to throw at compile.
513
- mdxError = err instanceof Error ? err.message : String(err);
514
- logger.warn(`[MDX] compile failed for ${pagePath}: ${mdxError}`);
519
+ });
520
+ } catch (err) {
521
+ // Syntax/compile failure — the only path that can 500 around MDXRemote.
522
+ // Degrade to an inline placeholder; the chosen branch renders it instead
523
+ // of calling MDXRemote with source known to throw at compile.
524
+ mdxError = err instanceof Error ? err.message : String(err);
525
+ logger.warn(`[MDX] compile failed for ${pagePath}: ${mdxError}`);
526
+ }
515
527
  }
516
528
  mdxCompileMs = Math.round(performance.now() - mdxCompileStart);
517
529
 
@@ -55,7 +55,8 @@ export type ScannerCategory =
55
55
  | 'secrets-config' // /secrets.yml, /application.yml, /vault.env, /elasticsearch.yml, etc.
56
56
  | 'cms-exploit' // Atlassian .action/.jspa + Confluence /exportword + /rest/tinymce/*
57
57
  | 'backup-archive' // /backup.sql, /*.zip, /*.tar.gz, /*.bak, /*.swp, /*.orig, etc.
58
- | 'framework-config'; // Django settings.py, webpack-stats.json, Laravel/Rails logs, Spring Boot /actuator|/management
58
+ | 'framework-config' // Django settings.py, webpack-stats.json, Laravel/Rails logs, Spring Boot /actuator|/management
59
+ | 'legacy-content'; // Confluence-legacy /download/(attachments|thumbnails|export) — stale-index re-crawls of dead migrated URLs, NOT exploit probes
59
60
 
60
61
  // Exact-match → category (lowercase keys).
61
62
  const SCANNER_EXACT: ReadonlyMap<string, ScannerCategory> = new Map([
@@ -63,6 +64,10 @@ const SCANNER_EXACT: ReadonlyMap<string, ScannerCategory> = new Map([
63
64
  ['/wp-config.php', 'wordpress' as const],
64
65
  ['/wp-config.php.bak', 'wordpress' as const],
65
66
  ['/xmlrpc.php', 'wordpress' as const],
67
+ // Bare WP install-dir probe (40 hits / 72h, 2026-06-12). Exact match
68
+ // ONLY — a customer docs site about WordPress may legitimately own
69
+ // /wordpress/<page>; only the bare root probe is scanner-distinctive.
70
+ ['/wordpress', 'wordpress' as const],
66
71
  ['/adminer.php', 'php-config' as const],
67
72
  ['/config.php', 'php-config' as const],
68
73
  ['/configuration.php', 'php-config' as const],
@@ -141,6 +146,24 @@ const CMS_EXPLOIT_EXTENSION_REGEX = /\.(action|jspa)$/;
141
146
  const CMS_EXPLOIT_TINYMCE_PREFIX = '/rest/tinymce/';
142
147
  const CMS_EXPLOIT_EXPORTWORD = '/exportword';
143
148
 
149
+ // Confluence-legacy download URL space: /download/attachments/<id>/…,
150
+ // /download/thumbnails/<id>/…, /download/export/pdfexport-<jobid>/….
151
+ // Stale crawlers replay these from pre-migration indexes (photofinale's
152
+ // old Confluence site); each otherwise costs an assets-route pass +
153
+ // ~300ms R2 GET before 404ing. The numeric content-ID segment /
154
+ // pdfexport- job prefix are the Confluence fingerprints —
155
+ // precision-over-recall: bare /download, non-numeric IDs, and other
156
+ // /download/export/* names intentionally do NOT match.
157
+ //
158
+ // NOTE: this check runs BEFORE tenant docs.json redirect resolution
159
+ // (proxy.ts step order), so matching paths can never be tenant redirect
160
+ // SOURCES. If a future Confluence-migration customer needs 301s over
161
+ // this URL space to preserve backlinks, this pattern must be revisited.
162
+ // Own category (not cms-exploit): these are benign stale re-crawls,
163
+ // and cms-exploit volume feeds the digest's WAF-promotion ranking.
164
+ const LEGACY_CONTENT_CONFLUENCE_DOWNLOAD_REGEX =
165
+ /^\/download\/(?:(?:attachments|thumbnails)\/\d+(?:\/|$)|export\/pdfexport-)/;
166
+
144
167
  // Prefix-match → category (lowercase). Matches the exact prefix OR `${prefix}/...`.
145
168
  // /actuator and /management cover Spring Boot management endpoints —
146
169
  // /management is the default-overridable base path (management.endpoints.web.base-path).
@@ -232,6 +255,8 @@ export function classifyScannerProbe(pathname: string): ScannerCategory | null {
232
255
  if (lower === CMS_EXPLOIT_EXPORTWORD) return 'cms-exploit';
233
256
  if (lower.startsWith(CMS_EXPLOIT_TINYMCE_PREFIX)) return 'cms-exploit';
234
257
 
258
+ if (LEGACY_CONTENT_CONFLUENCE_DOWNLOAD_REGEX.test(lower)) return 'legacy-content';
259
+
235
260
  if (BACKUP_ARCHIVE_EXTENSION_REGEX.test(lower)) return 'backup-archive';
236
261
 
237
262
  if (FRAMEWORK_BASENAMES.has(basename)) return 'framework-config';
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Sitemap XSL stylesheet — purely cosmetic, for humans who open sitemap.xml
3
+ * in a browser. Crawlers ignore the xml-stylesheet processing instruction.
4
+ *
5
+ * Served at /sitemap.xsl and /docs/sitemap.xsl by constant-content routes
6
+ * (no R2, identical for every project). The PI injected into sitemap.xml
7
+ * uses a RELATIVE href ("sitemap.xsl") so the same XML body resolves the
8
+ * stylesheet correctly from both /sitemap.xml and /docs/sitemap.xml —
9
+ * browsers require the XSL to be same-origin anyway.
10
+ *
11
+ * XSLT 1.0 only: that's all browser XSLT processors implement.
12
+ */
13
+
14
+ import { NextResponse } from 'next/server';
15
+
16
+ /** Processing instruction injected into served sitemap.xml bodies. */
17
+ export const SITEMAP_STYLESHEET_PI = '<?xml-stylesheet type="text/xsl" href="sitemap.xsl"?>';
18
+
19
+ /**
20
+ * Inject the stylesheet PI immediately after the XML declaration (the PI is
21
+ * only valid in the prolog, before the root element). Sitemaps without a
22
+ * declaration get it prepended. Idempotent: if a build-time generator ever
23
+ * starts baking a stylesheet PI into the R2 artifact, serve-time injection
24
+ * must not double it.
25
+ */
26
+ export function injectSitemapStylesheet(xml: string): string {
27
+ if (xml.includes('<?xml-stylesheet')) return xml;
28
+ const declMatch = xml.match(/^\uFEFF?<\?xml[^?]*\?>\r?\n?/);
29
+ if (declMatch) {
30
+ return declMatch[0] + SITEMAP_STYLESHEET_PI + '\n' + xml.slice(declMatch[0].length);
31
+ }
32
+ return SITEMAP_STYLESHEET_PI + '\n' + xml;
33
+ }
34
+
35
+ /**
36
+ * Shared GET handler for /sitemap.xsl and /docs/sitemap.xsl (same pattern as
37
+ * lib/api-specs-route.ts) - one place for the headers, two thin route files.
38
+ */
39
+ export function sitemapXslRouteHandler(): NextResponse {
40
+ return new NextResponse(SITEMAP_XSL, {
41
+ headers: {
42
+ 'Content-Type': 'text/xsl; charset=utf-8',
43
+ 'Cache-Control': 'public, max-age=86400, s-maxage=86400',
44
+ },
45
+ });
46
+ }
47
+
48
+ export const SITEMAP_XSL = `<?xml version="1.0" encoding="UTF-8"?>
49
+ <xsl:stylesheet version="1.0"
50
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
51
+ xmlns:sm="http://www.sitemaps.org/schemas/sitemap/0.9"
52
+ xmlns:xhtml="http://www.w3.org/1999/xhtml">
53
+ <xsl:output method="html" encoding="UTF-8" indent="yes"/>
54
+ <xsl:template match="/">
55
+ <html>
56
+ <head>
57
+ <title>XML Sitemap</title>
58
+ <meta name="viewport" content="width=device-width, initial-scale=1"/>
59
+ <style>
60
+ body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
61
+ margin: 0; padding: 2rem; color: #1a1a2e; background: #fafafa; }
62
+ h1 { font-size: 1.4rem; margin: 0 0 0.25rem; }
63
+ p.meta { color: #6b7280; margin: 0 0 1.5rem; font-size: 0.875rem; }
64
+ table { border-collapse: collapse; width: 100%; background: #fff;
65
+ border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden;
66
+ font-size: 0.875rem; }
67
+ th { text-align: left; padding: 0.6rem 0.9rem; background: #f3f4f6;
68
+ font-weight: 600; border-bottom: 1px solid #e5e7eb; white-space: nowrap; }
69
+ td { padding: 0.5rem 0.9rem; border-bottom: 1px solid #f3f4f6;
70
+ vertical-align: top; }
71
+ tr:last-child td { border-bottom: none; }
72
+ a { color: #4f46e5; text-decoration: none; word-break: break-all; }
73
+ a:hover { text-decoration: underline; }
74
+ .num { color: #9ca3af; text-align: right; }
75
+ .alt { color: #6b7280; white-space: nowrap; }
76
+ .alt a { color: #6b7280; }
77
+ .nowrap { white-space: nowrap; }
78
+ </style>
79
+ </head>
80
+ <body>
81
+ <h1>XML Sitemap</h1>
82
+ <p class="meta">
83
+ <xsl:value-of select="count(sm:urlset/sm:url)"/> URLs.
84
+ This is how the sitemap looks to humans; search engines read the raw XML.
85
+ </p>
86
+ <table>
87
+ <tr>
88
+ <th class="num">#</th>
89
+ <th>URL</th>
90
+ <xsl:if test="sm:urlset/sm:url/xhtml:link">
91
+ <th>Languages</th>
92
+ </xsl:if>
93
+ <th>Last modified</th>
94
+ <th>Change freq.</th>
95
+ <th>Priority</th>
96
+ </tr>
97
+ <xsl:for-each select="sm:urlset/sm:url">
98
+ <tr>
99
+ <td class="num"><xsl:value-of select="position()"/></td>
100
+ <td>
101
+ <a href="{sm:loc}"><xsl:value-of select="sm:loc"/></a>
102
+ </td>
103
+ <xsl:if test="/sm:urlset/sm:url/xhtml:link">
104
+ <td class="alt">
105
+ <xsl:for-each select="xhtml:link[@hreflang != 'x-default']">
106
+ <a href="{@href}"><xsl:value-of select="@hreflang"/></a>
107
+ <xsl:if test="position() != last()"><xsl:text> </xsl:text></xsl:if>
108
+ </xsl:for-each>
109
+ </td>
110
+ </xsl:if>
111
+ <td class="nowrap"><xsl:value-of select="sm:lastmod"/></td>
112
+ <td><xsl:value-of select="sm:changefreq"/></td>
113
+ <td><xsl:value-of select="sm:priority"/></td>
114
+ </tr>
115
+ </xsl:for-each>
116
+ </table>
117
+ </body>
118
+ </html>
119
+ </xsl:template>
120
+ </xsl:stylesheet>
121
+ `;
@@ -15,6 +15,7 @@ import { isKnownLanguageCode } from '@/lib/language-utils';
15
15
  import { log } from '@/lib/logger';
16
16
  import { isIsrMode } from '@/lib/page-isr-helpers';
17
17
  import { fetchStaticFile } from '@/lib/r2-content';
18
+ import { injectSitemapStylesheet } from '@/lib/sitemap-xsl';
18
19
 
19
20
  /** Filenames served via createStaticFileHandler (7 at root + 7 at /docs). */
20
21
  export const STATIC_FILE_NAMES = [
@@ -207,6 +208,10 @@ export function createStaticFileHandler(
207
208
  const contentType = contentTypeOverride || getContentType(filename);
208
209
  const cacheControl = cacheControlOverride || 'public, max-age=3600, s-maxage=3600';
209
210
  const synthesizeNoindexResponse = buildNoindexResponse(filename);
211
+ // Cosmetic browser rendering only — crawlers ignore the PI. Injected at
212
+ // serve time (not into the R2 artifact) so it ships with an ISR deploy
213
+ // alone: no Cloud Run change, no per-project rebuilds.
214
+ const postProcess = filename === 'sitemap.xml' ? injectSitemapStylesheet : (s: string) => s;
210
215
 
211
216
  return async function GET(request: NextRequest): Promise<NextResponse> {
212
217
  if (!isIsrMode()) {
@@ -216,7 +221,7 @@ export function createStaticFileHandler(
216
221
  // 404s on these paths and breaks the SearchModal init.
217
222
  const localPath = path.join(process.cwd(), 'public', filename);
218
223
  if (fs.existsSync(localPath)) {
219
- return new NextResponse(fs.readFileSync(localPath), {
224
+ return new NextResponse(postProcess(fs.readFileSync(localPath, 'utf-8')), {
220
225
  headers: { 'Content-Type': contentType, 'Cache-Control': 'no-cache' },
221
226
  });
222
227
  }
@@ -245,7 +250,7 @@ export function createStaticFileHandler(
245
250
  return new NextResponse(`${label} not found`, { status: 404 });
246
251
  }
247
252
 
248
- return new NextResponse(content, {
253
+ return new NextResponse(postProcess(content), {
249
254
  headers: {
250
255
  'Content-Type': contentType,
251
256
  'Cache-Control': cacheControl,
@@ -1252,47 +1252,47 @@
1252
1252
  }
1253
1253
  },
1254
1254
  "node_modules/@tailwindcss/node": {
1255
- "version": "4.3.0",
1256
- "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.0.tgz",
1257
- "integrity": "sha512-aFb4gUhFOgdh9AXo4IzBEOzBkkAxm9VigwDJnMIYv3lcfXCJVesNfbEaBl4BNgVRyid92AmdviqwBUBRKSeY3g==",
1255
+ "version": "4.3.1",
1256
+ "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.1.tgz",
1257
+ "integrity": "sha512-6NDaqRoAMSXD1mr/RXu0HBvNE9a2n5tHPsxu9XHLws8o4Twes5rBM2205SUUiJ9goAtadrN6xTGX0UDEwp/N4A==",
1258
1258
  "license": "MIT",
1259
1259
  "dependencies": {
1260
1260
  "@jridgewell/remapping": "^2.3.5",
1261
- "enhanced-resolve": "^5.21.0",
1262
- "jiti": "^2.6.1",
1261
+ "enhanced-resolve": "5.21.6",
1262
+ "jiti": "^2.7.0",
1263
1263
  "lightningcss": "1.32.0",
1264
1264
  "magic-string": "^0.30.21",
1265
1265
  "source-map-js": "^1.2.1",
1266
- "tailwindcss": "4.3.0"
1266
+ "tailwindcss": "4.3.1"
1267
1267
  }
1268
1268
  },
1269
1269
  "node_modules/@tailwindcss/oxide": {
1270
- "version": "4.3.0",
1271
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.0.tgz",
1272
- "integrity": "sha512-F7HZGBeN9I0/AuuJS5PwcD8xayx5ri5GhjYUDBEVYUkexyA/giwbDNjRVrxSezE3T250OU2K/wp/ltWx3UOefg==",
1270
+ "version": "4.3.1",
1271
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.1.tgz",
1272
+ "integrity": "sha512-yVPyo8RNkabVr3O2EhHEE0Rewu7YKzc1DhIqfL46LKveFrmu9XbDazNOJY7/GRuvw1h6u3utWnR29H/p5JPlgA==",
1273
1273
  "license": "MIT",
1274
1274
  "engines": {
1275
1275
  "node": ">= 20"
1276
1276
  },
1277
1277
  "optionalDependencies": {
1278
- "@tailwindcss/oxide-android-arm64": "4.3.0",
1279
- "@tailwindcss/oxide-darwin-arm64": "4.3.0",
1280
- "@tailwindcss/oxide-darwin-x64": "4.3.0",
1281
- "@tailwindcss/oxide-freebsd-x64": "4.3.0",
1282
- "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.0",
1283
- "@tailwindcss/oxide-linux-arm64-gnu": "4.3.0",
1284
- "@tailwindcss/oxide-linux-arm64-musl": "4.3.0",
1285
- "@tailwindcss/oxide-linux-x64-gnu": "4.3.0",
1286
- "@tailwindcss/oxide-linux-x64-musl": "4.3.0",
1287
- "@tailwindcss/oxide-wasm32-wasi": "4.3.0",
1288
- "@tailwindcss/oxide-win32-arm64-msvc": "4.3.0",
1289
- "@tailwindcss/oxide-win32-x64-msvc": "4.3.0"
1278
+ "@tailwindcss/oxide-android-arm64": "4.3.1",
1279
+ "@tailwindcss/oxide-darwin-arm64": "4.3.1",
1280
+ "@tailwindcss/oxide-darwin-x64": "4.3.1",
1281
+ "@tailwindcss/oxide-freebsd-x64": "4.3.1",
1282
+ "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.1",
1283
+ "@tailwindcss/oxide-linux-arm64-gnu": "4.3.1",
1284
+ "@tailwindcss/oxide-linux-arm64-musl": "4.3.1",
1285
+ "@tailwindcss/oxide-linux-x64-gnu": "4.3.1",
1286
+ "@tailwindcss/oxide-linux-x64-musl": "4.3.1",
1287
+ "@tailwindcss/oxide-wasm32-wasi": "4.3.1",
1288
+ "@tailwindcss/oxide-win32-arm64-msvc": "4.3.1",
1289
+ "@tailwindcss/oxide-win32-x64-msvc": "4.3.1"
1290
1290
  }
1291
1291
  },
1292
1292
  "node_modules/@tailwindcss/oxide-android-arm64": {
1293
- "version": "4.3.0",
1294
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.0.tgz",
1295
- "integrity": "sha512-TJPiq67tKlLuObP6RkwvVGDoxCMBVtDgKkLfa/uyj7/FyxvQwHS+UOnVrXXgbEsfUaMgiVvC4KbJnRr26ho4Ng==",
1293
+ "version": "4.3.1",
1294
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.1.tgz",
1295
+ "integrity": "sha512-SVlyf61g374l5cHyg8x9kf5xmLcOaxvOTsbsqDnSsDJaKOEFZ7GCvi84VAVGpxojYOs1+3K6M0UjXfqPU8vmOQ==",
1296
1296
  "cpu": [
1297
1297
  "arm64"
1298
1298
  ],
@@ -1306,9 +1306,9 @@
1306
1306
  }
1307
1307
  },
1308
1308
  "node_modules/@tailwindcss/oxide-darwin-arm64": {
1309
- "version": "4.3.0",
1310
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.0.tgz",
1311
- "integrity": "sha512-oMN/WZRb+SO37BmUElEgeEWuU8E/HXRkiODxJxLe1UTHVXLrdVSgfaJV7pSlhRGMSOiXLuxTIjfsF3wYvz8cgQ==",
1309
+ "version": "4.3.1",
1310
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.1.tgz",
1311
+ "integrity": "sha512-hVnWLwv+e/l7c4WKyVtHVrIPvYdqWHjRB3MDIqARynzFtnQg85kmQEFCbV9Ja0VVx4xXTIiDWY60Y7iz/iNoDA==",
1312
1312
  "cpu": [
1313
1313
  "arm64"
1314
1314
  ],
@@ -1322,9 +1322,9 @@
1322
1322
  }
1323
1323
  },
1324
1324
  "node_modules/@tailwindcss/oxide-darwin-x64": {
1325
- "version": "4.3.0",
1326
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.0.tgz",
1327
- "integrity": "sha512-N6CUmu4a6bKVADfw77p+iw6Yd9Q3OBhe0veaDX+QazfuVYlQsHfDgxBrsjQ/IW+zywL8mTrNd0SdJT/zgtvMdA==",
1325
+ "version": "4.3.1",
1326
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.1.tgz",
1327
+ "integrity": "sha512-Cf7abu0WVgbhU7ANgPUnSAvm7nCvMweusHb8FnaHlLfv/Caq4GYaEZg7ZImzzmjx4lIAfuS8q+eLIS7A7IzxIg==",
1328
1328
  "cpu": [
1329
1329
  "x64"
1330
1330
  ],
@@ -1338,9 +1338,9 @@
1338
1338
  }
1339
1339
  },
1340
1340
  "node_modules/@tailwindcss/oxide-freebsd-x64": {
1341
- "version": "4.3.0",
1342
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.0.tgz",
1343
- "integrity": "sha512-zDL5hBkQdH5C6MpqbK3gQAgP80tsMwSI26vjOzjJtNCMUo0lFgOItzHKBIupOZNQxt3ouPH7RPhvNhiTfCe5CQ==",
1341
+ "version": "4.3.1",
1342
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.1.tgz",
1343
+ "integrity": "sha512-ZZqzX2Y+GXtXXfqSfpJhDm60OoZfvLHLCgm+J7NVqgHHJjG/m9ugZI77RwTsVd4fnBJuCFP6Ae6kTJb71UdS8g==",
1344
1344
  "cpu": [
1345
1345
  "x64"
1346
1346
  ],
@@ -1354,9 +1354,9 @@
1354
1354
  }
1355
1355
  },
1356
1356
  "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
1357
- "version": "4.3.0",
1358
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.0.tgz",
1359
- "integrity": "sha512-R06HdNi7A7OEoMsf6d4tjZ71RCWnZQPHj2mnotSFURjNLdBC+cIgXQ7l81CqeoiQftjf6OOblxXMInMgN2VzMA==",
1357
+ "version": "4.3.1",
1358
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.1.tgz",
1359
+ "integrity": "sha512-/Ah/xik0LaMYfv9DZ0S/t4pBlBNYOcqtRwusjgovHkvT8ixueWCLyJjsaF5kQIckjb4IT8Q6K6p/iPmZMixYgg==",
1360
1360
  "cpu": [
1361
1361
  "arm"
1362
1362
  ],
@@ -1370,9 +1370,9 @@
1370
1370
  }
1371
1371
  },
1372
1372
  "node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
1373
- "version": "4.3.0",
1374
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.0.tgz",
1375
- "integrity": "sha512-qTJHELX8jetjhRQHCLilkVLmybpzNQAtaI/gaoVoidn/ufbNDbAo8KlK2J+yPoc8wQxvDxCmh/5lr8nC1+lTbg==",
1373
+ "version": "4.3.1",
1374
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.1.tgz",
1375
+ "integrity": "sha512-gqdFoVJlw444GvpnheZLHmvTzSxI/cOUUh2KSNejQjTcYkW062SVD+En0rUgD+QV91bz1XGIGtt1HJd48xUGbQ==",
1376
1376
  "cpu": [
1377
1377
  "arm64"
1378
1378
  ],
@@ -1389,9 +1389,9 @@
1389
1389
  }
1390
1390
  },
1391
1391
  "node_modules/@tailwindcss/oxide-linux-arm64-musl": {
1392
- "version": "4.3.0",
1393
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.0.tgz",
1394
- "integrity": "sha512-Z6sukiQsngnWO+l39X4pPbiWT81IC+PLKF+PHxIlyZbGNb9MODfYlXEVlFvej5BOZInWX01kVyzeLvHsXhfczQ==",
1392
+ "version": "4.3.1",
1393
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.1.tgz",
1394
+ "integrity": "sha512-Bwv9KwOvE0VKa86xPFif9b9c3Y1NxOV1P0gLti/IYaWEsQYZXDlxfGEtA8mdDZ7SG3wyNXAWYT5SIn3giL57oA==",
1395
1395
  "cpu": [
1396
1396
  "arm64"
1397
1397
  ],
@@ -1408,9 +1408,9 @@
1408
1408
  }
1409
1409
  },
1410
1410
  "node_modules/@tailwindcss/oxide-linux-x64-gnu": {
1411
- "version": "4.3.0",
1412
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.0.tgz",
1413
- "integrity": "sha512-DRNdQRpSGzRGfARVuVkxvM8Q12nh19l4BF/G7zGA1oe+9wcC6saFBHTISrpIcKzhiXtSrlSrluCfvMuledoCTQ==",
1411
+ "version": "4.3.1",
1412
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.1.tgz",
1413
+ "integrity": "sha512-Ymi8O8T15HYQdOUWUtTI6ldN0neHP85FC+Qz32xTcZ7iJXtem/x8ITev0o1e9e5rkqj4lONZfTRLvkmin1+tKg==",
1414
1414
  "cpu": [
1415
1415
  "x64"
1416
1416
  ],
@@ -1427,9 +1427,9 @@
1427
1427
  }
1428
1428
  },
1429
1429
  "node_modules/@tailwindcss/oxide-linux-x64-musl": {
1430
- "version": "4.3.0",
1431
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.0.tgz",
1432
- "integrity": "sha512-Z0IADbDo8bh6I7h2IQMx601AdXBLfFpEdUotft86evd/8ZPflZe9COPO8Q1vw+pfLWIUo9zN/JGZvwuAJqduqg==",
1430
+ "version": "4.3.1",
1431
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.1.tgz",
1432
+ "integrity": "sha512-M+P/91qJ6uILLw4k2G93GMDRAXj61SMvFQYt39AqvUqYgExXpLL5aepfns7sj4HiAQeolirQF9E0lzRvdf4zPQ==",
1433
1433
  "cpu": [
1434
1434
  "x64"
1435
1435
  ],
@@ -1446,9 +1446,9 @@
1446
1446
  }
1447
1447
  },
1448
1448
  "node_modules/@tailwindcss/oxide-wasm32-wasi": {
1449
- "version": "4.3.0",
1450
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.0.tgz",
1451
- "integrity": "sha512-HNZGOUxEmElksYR7S6sC5jTeNGpobAsy9u7Gu0AskJ8/20FR9GqebUyB+HBcU/ax6BHuiuJi+Oda4B+YX6H1yA==",
1449
+ "version": "4.3.1",
1450
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.1.tgz",
1451
+ "integrity": "sha512-zsM8uOeqvVGHsAXsJxsT28ttosFahLJKCLOTUBqRAtKnVgGSRitds9T432QiT8b77Yga7JIBkulIRRlJPtYhRA==",
1452
1452
  "bundleDependencies": [
1453
1453
  "@napi-rs/wasm-runtime",
1454
1454
  "@emnapi/core",
@@ -1467,7 +1467,7 @@
1467
1467
  "@emnapi/runtime": "^1.10.0",
1468
1468
  "@emnapi/wasi-threads": "^1.2.1",
1469
1469
  "@napi-rs/wasm-runtime": "^1.1.4",
1470
- "@tybys/wasm-util": "^0.10.1",
1470
+ "@tybys/wasm-util": "^0.10.2",
1471
1471
  "tslib": "^2.8.1"
1472
1472
  },
1473
1473
  "engines": {
@@ -1520,7 +1520,7 @@
1520
1520
  }
1521
1521
  },
1522
1522
  "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": {
1523
- "version": "0.10.1",
1523
+ "version": "0.10.2",
1524
1524
  "inBundle": true,
1525
1525
  "license": "MIT",
1526
1526
  "optional": true,
@@ -1535,9 +1535,9 @@
1535
1535
  "optional": true
1536
1536
  },
1537
1537
  "node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
1538
- "version": "4.3.0",
1539
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.0.tgz",
1540
- "integrity": "sha512-Pe+RPVTi1T+qymuuRpcdvwSVZjnll/f7n8gBxMMh3xLTctMDKqpdfGimbMyioqtLhUYZxdJ9wGNhV7MKHvgZsQ==",
1538
+ "version": "4.3.1",
1539
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.1.tgz",
1540
+ "integrity": "sha512-aiNvSq9BsVk8V513lDKlrCFAgf8qBMPZTpgEhInL+NwQqs97mYmupVMrPrgBBSL8Pv/0zXu9MrMF9rMun1ZeNg==",
1541
1541
  "cpu": [
1542
1542
  "arm64"
1543
1543
  ],
@@ -1551,9 +1551,9 @@
1551
1551
  }
1552
1552
  },
1553
1553
  "node_modules/@tailwindcss/oxide-win32-x64-msvc": {
1554
- "version": "4.3.0",
1555
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.0.tgz",
1556
- "integrity": "sha512-Mvrf2kXW/yeW/OTezZlCGOirXRcUuLIBx/5Y12BaPM7wJoryG6dfS/NJL8aBPqtTEx/Vm4T4vKzFUcKDT+TKUA==",
1554
+ "version": "4.3.1",
1555
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.1.tgz",
1556
+ "integrity": "sha512-xDEyu1rg290472FEGaKHnzyDyh5QH+AlWvsU5hMoMtPpzmKlRI0jaYKCgSHDYtaQWZOYbMaduSyCwFwY4n1HmA==",
1557
1557
  "cpu": [
1558
1558
  "x64"
1559
1559
  ],
@@ -1567,16 +1567,16 @@
1567
1567
  }
1568
1568
  },
1569
1569
  "node_modules/@tailwindcss/postcss": {
1570
- "version": "4.3.0",
1571
- "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.3.0.tgz",
1572
- "integrity": "sha512-Jm05Tjx+9yCLGv5qw1c+84Psds8MnyrEQYCB+FFk2lgGiUjlRqdxke4mVTuYrj2xnVZqKim2Apr5ySuQRYAw/w==",
1570
+ "version": "4.3.1",
1571
+ "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.3.1.tgz",
1572
+ "integrity": "sha512-dNJuNbdEJT/SWRuXTYP1WSamelsz3ztkUsdtWQPjrexysrTpaEPM40P/71knXiXLYEojqPOEGitVLLpPMS5T6A==",
1573
1573
  "license": "MIT",
1574
1574
  "dependencies": {
1575
1575
  "@alloc/quick-lru": "^5.2.0",
1576
- "@tailwindcss/node": "4.3.0",
1577
- "@tailwindcss/oxide": "4.3.0",
1578
- "postcss": "^8.5.10",
1579
- "tailwindcss": "4.3.0"
1576
+ "@tailwindcss/node": "4.3.1",
1577
+ "@tailwindcss/oxide": "4.3.1",
1578
+ "postcss": "8.5.15",
1579
+ "tailwindcss": "4.3.1"
1580
1580
  }
1581
1581
  },
1582
1582
  "node_modules/@tailwindcss/typography": {
@@ -2145,9 +2145,9 @@
2145
2145
  }
2146
2146
  },
2147
2147
  "node_modules/baseline-browser-mapping": {
2148
- "version": "2.10.36",
2149
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.36.tgz",
2150
- "integrity": "sha512-lVq/Df7LXlO79MVaaUHztSwWiG9oXoWHlgvNS51v8Dpd4+G4/VIy6qYePTw31nAVls33nUtnfezYeLkYAak9dg==",
2148
+ "version": "2.10.37",
2149
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.37.tgz",
2150
+ "integrity": "sha512-girxaJ7WZssDOFhzCGZTDKoTa1gk6A1TbflaYTpykLJ4UU9Fz9kx1aREM8JCuoVHbL8X8T/mJg7w2oYSq72Oig==",
2151
2151
  "license": "Apache-2.0",
2152
2152
  "bin": {
2153
2153
  "baseline-browser-mapping": "dist/cli.cjs"
@@ -2924,9 +2924,9 @@
2924
2924
  }
2925
2925
  },
2926
2926
  "node_modules/dompurify": {
2927
- "version": "3.4.9",
2928
- "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.9.tgz",
2929
- "integrity": "sha512-4dPSRMRDqHvs0V4YDFCsaIZo4if5u0xM+llyxiM2fwuZFdKArUBAF3VtI2+n8NKg9P870WMdYk0UhqQNoWXbfQ==",
2927
+ "version": "3.4.10",
2928
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.10.tgz",
2929
+ "integrity": "sha512-0xzNv0e7oYC6yyuOGZIABPM4qtg3QxLFniDNPP4ZP90wR8Yq3zgwpRbrNiT4N3IKqDbbYFEJLV+JWEs19aZ//w==",
2930
2930
  "license": "(MPL-2.0 OR Apache-2.0)",
2931
2931
  "optionalDependencies": {
2932
2932
  "@types/trusted-types": "^2.0.7"
@@ -2939,15 +2939,15 @@
2939
2939
  "license": "MIT"
2940
2940
  },
2941
2941
  "node_modules/electron-to-chromium": {
2942
- "version": "1.5.371",
2943
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.371.tgz",
2944
- "integrity": "sha512-e9htk9mAYL6AzmkEhSvVVw7IWGSBJ/Bqdn2eRyRLrj1g6sncN4WbFt5qnILYoCktktr45pyjIrOiRvBThQ808w==",
2942
+ "version": "1.5.372",
2943
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.372.tgz",
2944
+ "integrity": "sha512-M3yhbAlilnwqC8D21t28UCDGHyitShTmmLRU/H+b74P6Ski16Nb9HONYEaVpMj/pwC7BEo5B95FpjODLCWbtfA==",
2945
2945
  "license": "ISC"
2946
2946
  },
2947
2947
  "node_modules/enhanced-resolve": {
2948
- "version": "5.24.0",
2949
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.0.tgz",
2950
- "integrity": "sha512-SkE2t82KlkkxQRVMVLAGKxLfORGQfrkx5dkj+vlgXRVNEdPc4eZcR+J/Fvj8C+yKSFH5L0q3NFlyufOVQnCcYQ==",
2948
+ "version": "5.21.6",
2949
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.6.tgz",
2950
+ "integrity": "sha512-aNnGCvbJ/RIyWo1IuhNdVjnNF+EjH9wpzpNHt+ci/m9He9LJvUN8wrCcXjp9cWsGNAuvSpVFTx/vraAFQ8qGjQ==",
2951
2951
  "license": "MIT",
2952
2952
  "dependencies": {
2953
2953
  "graceful-fs": "^4.2.4",
@@ -2970,9 +2970,9 @@
2970
2970
  }
2971
2971
  },
2972
2972
  "node_modules/es-toolkit": {
2973
- "version": "1.47.0",
2974
- "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.47.0.tgz",
2975
- "integrity": "sha512-n1GuoD0WEQZMBk5tttoZSqwgyLx01oqa5XsBmCHwPyNe1S9jPBEmtR2pSgp2kJuWE3ciFZ6yRHmY4pM4C3OOkw==",
2973
+ "version": "1.47.1",
2974
+ "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.47.1.tgz",
2975
+ "integrity": "sha512-5RAqEwf4P4E17p+W75KLOWw/nOvKZzSQpxM32IpI2KZLaVonjTrZ0Ai5ghMaVI9eKC2p8eoQgcBdkEDgzFk6+Q==",
2976
2976
  "license": "MIT",
2977
2977
  "workspaces": [
2978
2978
  "docs",
@@ -6269,9 +6269,9 @@
6269
6269
  "license": "MIT"
6270
6270
  },
6271
6271
  "node_modules/tailwindcss": {
6272
- "version": "4.3.0",
6273
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.0.tgz",
6274
- "integrity": "sha512-y6nxMGB1nMW9R6k96e5gdIFzcfL/gTJRNaqGes1YvkLnPVXzWgbqFF2yLC0T8G774n24cx3Pe8XrKoniCOAH+Q==",
6272
+ "version": "4.3.1",
6273
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.1.tgz",
6274
+ "integrity": "sha512-hk+TB1m+K8CYNrP6rjQaq/Y+4Zylwpa87mLYBKCunwnnQ9p+fHb7kmSfGqyEJoxF/O6CDyABWVFEafNSYKll+Q==",
6275
6275
  "license": "MIT"
6276
6276
  },
6277
6277
  "node_modules/tapable": {