@anthusai/papyrus 5.41.2 → 5.41.4

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/app/globals.css CHANGED
@@ -10170,3 +10170,32 @@ img {
10170
10170
  }
10171
10171
  }
10172
10172
 
10173
+
10174
+ @media (max-width: 900px) {
10175
+ .edition-progress__button--console { display: none; }
10176
+ .papyrus-console--open {
10177
+ --papyrus-console-width: 100vw;
10178
+ background: rgb(var(--paper-rgb));
10179
+ height: 100dvh;
10180
+ padding-bottom: env(safe-area-inset-bottom);
10181
+ box-sizing: border-box;
10182
+ }
10183
+ }
10184
+
10185
+ .papyrus-console__access {
10186
+ display: flex;
10187
+ flex-direction: column;
10188
+ align-items: flex-start;
10189
+ gap: 16px;
10190
+ padding: 24px 18px;
10191
+ overflow-y: auto;
10192
+ color: var(--ink);
10193
+ font-size: 0.95rem;
10194
+ line-height: 1.5;
10195
+ }
10196
+ .papyrus-console__access strong { font-size: 1.15rem; }
10197
+ .papyrus-console__access button { min-height: 44px; padding: 10px 14px; font: inherit; text-transform: none; letter-spacing: normal; }
10198
+
10199
+ @media (max-width: 900px) {
10200
+ .papyrus-console__header button { min-width: 44px; min-height: 44px; }
10201
+ }
@@ -0,0 +1,23 @@
1
+ "use client";
2
+
3
+ import type { ReactNode } from "react";
4
+ import Link from "next/link";
5
+ import { BookOpen, ClipboardList, House, MessageCircle, MessagesSquare } from "lucide-react";
6
+
7
+ const ICONS = { overview: House, articles: ClipboardList, references: BookOpen, messages: MessagesSquare };
8
+
9
+ export function NewsroomMobileNavigation({ items, activeTab, chat, more }: {
10
+ items: readonly { key: string; label: string; description: string; href: string }[];
11
+ activeTab: string;
12
+ chat?: { open: boolean; onOpen: () => void };
13
+ more: ReactNode;
14
+ }) {
15
+ return <nav className="organizer-bottom-nav" aria-label="Primary newsroom navigation"><ul>
16
+ {items.map(item => {
17
+ if (item.key === "messages" && chat) return <li key="chat"><button className="organizer-chat" type="button" aria-label="Open private chat" aria-expanded={chat.open} aria-controls="papyrus-console-panel" onClick={chat.onOpen}><MessageCircle size={18} aria-hidden="true" /><span>Chat</span></button></li>;
18
+ const Icon = ICONS[item.key as keyof typeof ICONS];
19
+ return <li key={item.key}><Link href={item.href} title={item.description} aria-label={item.label} aria-current={activeTab === item.key ? "page" : undefined}><Icon size={18} aria-hidden="true" /><span>{item.label}</span></Link></li>;
20
+ })}
21
+ <li>{more}</li>
22
+ </ul></nav>;
23
+ }
@@ -8,7 +8,7 @@ import { cn } from "../lib/utils";
8
8
  import { useEffect, useId, useState, type ReactNode } from "react";
9
9
  import Link from "next/link";
10
10
  import { usePathname, useRouter, useSearchParams } from "next/navigation";
11
- import { BookOpen, ClipboardList, House, Menu, Search, MessagesSquare, PanelLeftClose, PanelLeftOpen, Settings, UserRound, LogIn, LogOut } from "lucide-react";
11
+ import { Menu, Search, PanelLeftClose, PanelLeftOpen, Settings, UserRound, LogIn, LogOut } from "lucide-react";
12
12
  import { ORGANIZER_NAV_GROUPS, ORGANIZER_PRIMARY_NAV, ORGANIZER_SETTINGS_DESTINATION } from "../lib/newsroom-organizer-nav";
13
13
  import { browserPathToInternalNewsroomPath } from "../lib/newsroom-base-path";
14
14
  import { getNewsroomNavHref } from "../lib/newsroom-nav";
@@ -20,6 +20,8 @@ import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetTr
20
20
  import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuLabel, DropdownMenuItem, DropdownMenuSeparator } from "./ui/dropdown-menu";
21
21
  import "./newsroom-organizer.css";
22
22
  import { NewsroomThemeFonts, useNewsroomThemeAttributes } from "./newsroom-theme";
23
+ import { NewsroomMobileNavigation } from "./newsroom-mobile-navigation";
24
+ import { usePapyrusConsole } from "./papyrus-console-shell";
23
25
 
24
26
  export type NewsroomNavCount = {
25
27
  count: number | null;
@@ -55,8 +57,6 @@ function OrganizerSearch({ demo }: { demo: boolean }) {
55
57
  </form>;
56
58
  }
57
59
 
58
- const ICONS = { overview: House, articles: ClipboardList, references: BookOpen, messages: MessagesSquare };
59
-
60
60
  /** Navigation is a presentation layer; existing route and server authorization still own access. */
61
61
  function Navigation({ activePath, demo, admin, surface, onNavigate }: { activePath: string; demo: boolean; admin: boolean; surface: string; onNavigate?: () => void }) {
62
62
  const id = useId();
@@ -105,6 +105,7 @@ function Account({ placement }: { placement: "sidebar" | "header" }) {
105
105
  }
106
106
 
107
107
  export function NewsroomOpsShell({ activeTab, appTitle, backHref = "/", backLabel, children, demo = false, headerActions, pageTitle, showNavigation = true }: NewsroomOpsShellProps) {
108
+ const consoleState = usePapyrusConsole();
108
109
  const pathname = usePathname();
109
110
  const themeAttributes = useNewsroomThemeAttributes();
110
111
  const session = useOptionalNewsDeskClient();
@@ -166,16 +167,13 @@ export function NewsroomOpsShell({ activeTab, appTitle, backHref = "/", backLabe
166
167
  </header>
167
168
  <main className="organizer-main">{demo && <p className="organizer-demo-notice">Demo workspace · synthetic examples</p>}{children}</main>
168
169
  </div>
169
- {showNavigation && <nav className="organizer-bottom-nav" aria-label="Primary newsroom navigation"><ul>
170
- {ORGANIZER_PRIMARY_NAV.map(item => { const Icon = ICONS[item.key as keyof typeof ICONS]; return <li key={item.key}><Link
171
- href={getNewsroomNavHref(item.path, demo)} title={item.description} aria-label={item.label} aria-current={activeTab === item.key ? "page" : undefined}>
172
- <Icon size={18} aria-hidden="true" /><span>{item.label}</span></Link></li>; })}
173
- <li><Sheet open={menuOpen} onOpenChange={setMenuOpen}><SheetTrigger className="organizer-more" aria-label="More"><Menu size={18} aria-hidden="true" /><span>More</span></SheetTrigger>
170
+ {showNavigation && <NewsroomMobileNavigation activeTab={activeTab} items={ORGANIZER_PRIMARY_NAV.map(item => ({ ...item, href: getNewsroomNavHref(item.path, demo) }))}
171
+ chat={consoleState?.shouldOfferConsole ? { open: consoleState.open, onOpen: consoleState.openConsole } : undefined}
172
+ more={<Sheet open={menuOpen} onOpenChange={setMenuOpen}><SheetTrigger className="organizer-more" aria-label="More"><Menu size={18} aria-hidden="true" /><span>More</span></SheetTrigger>
174
173
  <SheetContent side="bottom" className="organizer-menu" {...themeAttributes}><SheetHeader><SheetTitle>Newsroom</SheetTitle><SheetDescription>Workspaces and administration</SheetDescription></SheetHeader>
175
174
  <Navigation activePath={activePath} demo={demo} admin={admin} surface="menu" onNavigate={() => setMenuOpen(false)} />
176
175
  </SheetContent>
177
- </Sheet></li>
178
- </ul></nav>}
176
+ </Sheet>} />}
179
177
  </div>;
180
178
  }
181
179
 
@@ -33,6 +33,7 @@ body:has(.newsroom-organizer)>[data-staging-banner]{flex-shrink:0}
33
33
  .organizer-account-popup{min-width:250px;max-width:calc(100vw - 32px);border:1px solid var(--org-line);padding:6px;border-radius:4px}
34
34
  .organizer-account-popup [role=menuitem]{min-height:40px;font-size:12px}.organizer-account-popup .reader-auth{display:contents}.organizer-account-popup .reader-auth__error{display:block;white-space:normal;font-size:11px;padding:8px}
35
35
  .organizer-bottom-nav{display:none}
36
+ .organizer-bottom-nav button{appearance:none;border:0;background:transparent;color:inherit}
36
37
  .organizer-main:has(.organizer-native-board){display:flex;overflow:hidden}
37
38
  .organizer-native-board{display:flex;flex-direction:column;flex:1;min-height:0;min-width:0;gap:8px}
38
39
  .organizer-board-view-toggle{display:flex;gap:4px;flex-shrink:0}
@@ -0,0 +1,66 @@
1
+ "use client";
2
+
3
+ import { useEffect, useRef, useState, type ReactNode } from "react";
4
+
5
+ export function PapyrusConsoleFrame({ available, open, reserveSpace, onClose, page, children }: {
6
+ available: boolean;
7
+ open: boolean;
8
+ reserveSpace: boolean;
9
+ onClose: () => void;
10
+ page: ReactNode;
11
+ children: ReactNode;
12
+ }) {
13
+ const [mobile, setMobile] = useState(false);
14
+ const [viewport, setViewport] = useState<{ top: number; height: number } | null>(null);
15
+ const panel = useRef<HTMLElement>(null);
16
+ const modal = available && open && mobile;
17
+
18
+ useEffect(() => {
19
+ const media = window.matchMedia("(max-width: 900px)");
20
+ const update = () => setMobile(media.matches);
21
+ update();
22
+ media.addEventListener("change", update);
23
+ return () => media.removeEventListener("change", update);
24
+ }, []);
25
+
26
+ useEffect(() => {
27
+ if (!modal) return;
28
+ const visual = window.visualViewport;
29
+ const update = () => setViewport({ top: visual?.offsetTop ?? 0, height: visual?.height ?? window.innerHeight });
30
+ update();
31
+ visual?.addEventListener("resize", update);
32
+ visual?.addEventListener("scroll", update, { passive: true });
33
+ return () => {
34
+ visual?.removeEventListener("resize", update);
35
+ visual?.removeEventListener("scroll", update);
36
+ };
37
+ }, [modal]);
38
+
39
+ useEffect(() => {
40
+ if (!modal) return;
41
+ const previous = document.activeElement;
42
+ const frame = requestAnimationFrame(() => panel.current?.querySelector<HTMLElement>("button")?.focus());
43
+ return () => {
44
+ cancelAnimationFrame(frame);
45
+ requestAnimationFrame(() => {
46
+ if (previous instanceof HTMLElement && previous !== document.body && previous.isConnected && !previous.closest("[inert]")) previous.focus();
47
+ else Array.from(document.querySelectorAll<HTMLElement>(".organizer-chat, .edition-progress__button--console, .papyrus-console__header button")).find(element => element.getClientRects().length > 0)?.focus();
48
+ });
49
+ };
50
+ }, [modal]);
51
+
52
+ return <>
53
+ <div className={reserveSpace ? "papyrus-console-page papyrus-console-page--open" : "papyrus-console-page"} inert={modal || undefined}>{page}</div>
54
+ {available ? <aside ref={panel} id="papyrus-console-panel" className={open ? "papyrus-console papyrus-console--open" : "papyrus-console"} aria-label="Papyrus console" role={modal ? "dialog" : undefined} aria-modal={modal || undefined}
55
+ style={modal && viewport ? { top: viewport.top, height: viewport.height, bottom: "auto" } : undefined}
56
+ onKeyDown={event => {
57
+ if (!modal) return;
58
+ if (event.key === "Escape") { event.preventDefault(); onClose(); return; }
59
+ if (event.key !== "Tab") return;
60
+ const focusable = Array.from(panel.current?.querySelectorAll<HTMLElement>('button:not(:disabled), a[href], input:not(:disabled), textarea:not(:disabled), select:not(:disabled), [tabindex="0"]') ?? []).filter(element => element.getClientRects().length > 0);
61
+ const first = focusable[0], last = focusable.at(-1);
62
+ if (event.shiftKey && document.activeElement === first) { event.preventDefault(); last?.focus(); }
63
+ else if (!event.shiftKey && document.activeElement === last) { event.preventDefault(); first?.focus(); }
64
+ }}>{children}</aside> : null}
65
+ </>;
66
+ }
@@ -35,6 +35,8 @@ import {
35
35
  type ReaderMotionSetting,
36
36
  } from "./reader-settings";
37
37
  import { PapyrusConsoleConversation, type ConsoleConversationMessage } from "./papyrus-console-conversation";
38
+ import { PapyrusConsoleFrame } from "./papyrus-console-frame";
39
+ import { useConsoleVisibility } from "./use-console-visibility";
38
40
  import { PapyrusPrivateChatPanel } from "./papyrus-private-chat-panel";
39
41
  import { ModelSelector } from "./ai-elements/model-selector";
40
42
  import { Suggestion, Suggestions } from "./ai-elements/suggestion";
@@ -149,12 +151,12 @@ const PapyrusConsoleContext = createContext<PapyrusConsoleContextValue | null>(n
149
151
  export function PapyrusConsoleShell({ children, privateChatEnabled = false }: PapyrusConsoleShellProps) {
150
152
  const pathname = usePathname();
151
153
  const [session, setSession] = useState<ReaderSessionSnapshot | null>(null);
152
- const [open, setOpen] = useState(false);
153
154
  const [openingReferenceChat, setOpeningReferenceChat] = useState(false);
154
155
  const internalPathname = browserPathToInternalNewsroomPath(pathname);
155
156
  const isNewsroomPath = internalPathname === "/newsroom" || internalPathname.startsWith("/newsroom/");
156
157
  const canUseConsole = Boolean(session?.hasSession && session.groups.some((group) => group === "editor" || group === "admin"));
157
158
  const shouldOfferConsole = isNewsroomPath && canUseConsole;
159
+ const { open, openConsole, closeConsole, toggleOpen } = useConsoleVisibility({ available: shouldOfferConsole });
158
160
 
159
161
  useEffect(() => {
160
162
  let active = true;
@@ -165,37 +167,11 @@ export function PapyrusConsoleShell({ children, privateChatEnabled = false }: Pa
165
167
  .catch(() => {
166
168
  if (active) setSession({ auth: { status: "signedOut", label: "Signed out" }, groups: [], hasSession: false });
167
169
  });
168
- try {
169
- setOpen(window.localStorage.getItem("papyrus:console-open") === "true");
170
- } catch {
171
- setOpen(false);
172
- }
173
170
  return () => {
174
171
  active = false;
175
172
  };
176
173
  }, []);
177
174
 
178
- const toggleOpen = useCallback(() => {
179
- setOpen((current) => {
180
- const next = !current;
181
- try {
182
- window.localStorage.setItem("papyrus:console-open", String(next));
183
- } catch {
184
- // Ignore storage failures.
185
- }
186
- return next;
187
- });
188
- }, []);
189
-
190
- const openConsole = useCallback(() => {
191
- setOpen(true);
192
- try {
193
- window.localStorage.setItem("papyrus:console-open", "true");
194
- } catch {
195
- // Ignore storage failures.
196
- }
197
- }, []);
198
-
199
175
  const startReferenceChat = useCallback(async (target: NewsroomKnowledgeQueryTarget) => {
200
176
  if (!canUseConsole) {
201
177
  throw new Error("Chat is only available to editor/admin sessions.");
@@ -358,20 +334,15 @@ export function PapyrusConsoleShell({ children, privateChatEnabled = false }: Pa
358
334
 
359
335
  return (
360
336
  <PapyrusConsoleContext.Provider value={consoleContext}>
361
- <div className={canUseConsole && open ? "papyrus-console-page papyrus-console-page--open" : "papyrus-console-page"}>
362
- {children}
363
- </div>
364
- {shouldOfferConsole ? (
365
- <aside className={open ? "papyrus-console papyrus-console--open" : "papyrus-console"} aria-label="Papyrus console">
366
- {open ? (
367
- canUseConsole
368
- ? privateChatEnabled
369
- ? <PapyrusPrivateChatPanel onClose={toggleOpen} />
370
- : <ConsolePanel actorEmail={session?.auth.status === "signedIn" ? (session.auth.email ?? null) : null} actorLabel={session?.auth.label ?? "Papyrus editor"} onClose={toggleOpen} />
371
- : <ConsoleAccessPanel onClose={toggleOpen} session={session} />
372
- ) : null}
373
- </aside>
374
- ) : null}
337
+ <PapyrusConsoleFrame available={shouldOfferConsole} open={open} reserveSpace={canUseConsole && open} onClose={closeConsole} page={children}>
338
+ {open ? (
339
+ canUseConsole
340
+ ? privateChatEnabled
341
+ ? <PapyrusPrivateChatPanel onClose={closeConsole} />
342
+ : <ConsolePanel actorEmail={session?.auth.status === "signedIn" ? (session.auth.email ?? null) : null} actorLabel={session?.auth.label ?? "Papyrus editor"} onClose={closeConsole} />
343
+ : <ConsoleAccessPanel onClose={closeConsole} session={session} />
344
+ ) : null}
345
+ </PapyrusConsoleFrame>
375
346
  </PapyrusConsoleContext.Provider>
376
347
  );
377
348
  }
@@ -175,21 +175,26 @@ export function PapyrusPrivateChatPanel({ onClose }: { onClose: () => void }) {
175
175
  <button className="papyrus-console__close" onClick={onClose} type="button" aria-label="Close console">×</button>
176
176
  </header>
177
177
  {channel ? <p className="papyrus-console__empty" role="status">Private conversation for your selected Account.</p> : null}
178
- {!channel && !loading ? <div className="papyrus-console__empty" role="alert">
178
+ {!channel && !loading ? <div className="papyrus-console__access" role="alert">
179
179
  {error === "chat_identity_connection_required" ? <>
180
180
  <strong>Connect your publishing account</strong>
181
181
  {connectionNotice ? <span>{connectionNotice}</span> : null}
182
182
  <span>Continue with the same Google account you use in the newsroom, then choose the Account for this private conversation.</span>
183
183
  <button className="papyrus-console__new-session" disabled={connecting} onClick={() => void connect()} type="button">{connecting ? "Connecting…" : "Connect publishing account"}</button>
184
184
  </> : accountState?.status === "signedIn" ? <>
185
- <strong>Choose your publishing Account</strong>
186
- {accountState.publishingAccounts.length === 0 ? <span>This identity has no publishing Account for this site. Ask the Account owner to confirm your existing access.</span> : accountState.publishingAccounts.map(account => <button className="papyrus-console__new-session" disabled={connecting} key={account.accountId} onClick={() => void chooseAccount(account.accountId)} type="button">{account.name ?? account.accountId}</button>)}
185
+ <strong>{accountState.publishingAccounts.length === 0 ? "Chat access is unavailable" : "Choose your publishing Account"}</strong>
186
+ {accountState.publishingAccounts.length === 0 ? <>
187
+ <span>None of your Accounts is enabled for this publication. Publication setup must be resolved before you can chat.</span>
188
+ <span>You can return to the newsroom while this is resolved. Check again after access has been corrected.</span>
189
+ <button className="papyrus-console__new-session" onClick={() => void openConversation()} type="button">Check again</button>
190
+ </> : accountState.publishingAccounts.map(account => <button className="papyrus-console__new-session" disabled={connecting} key={account.accountId} onClick={() => void chooseAccount(account.accountId)} type="button">{account.name ?? account.accountId}</button>)}
187
191
  {error !== "publishing_account_required" ? <span>{error}</span> : null}
188
192
  </> : <>
189
193
  <strong>Private chat could not be opened.</strong>
190
- <span>{error === "sign_in_required" ? "Your newsroom session has expired. Sign in from the account menu, then retry." : error}</span>
194
+ <span>{error === "sign_in_required" ? "Your newsroom session has expired. Return to the newsroom and sign in from the account menu, then retry." : error === "chat_account_access_denied" ? "Your access to this conversation has changed. Retry to check your current access." : error === "publishing_account_required" ? "Publishing Account access could not be checked. Retry when your connection is available." : error}</span>
191
195
  <button className="papyrus-console__new-session" onClick={() => void openConversation()} type="button">Retry</button>
192
196
  </>}
197
+ <button className="papyrus-console__new-session" onClick={onClose} type="button">Back to newsroom</button>
193
198
  </div> : <PapyrusConsoleConversation
194
199
  messages={conversationMessages}
195
200
  isSending={sending || loading || !channel}
@@ -0,0 +1,47 @@
1
+ "use client";
2
+
3
+ import { useCallback, useEffect, useRef, useState } from "react";
4
+
5
+ export function useConsoleVisibility({ available, persist = true }: { available: boolean; persist?: boolean }) {
6
+ const [open, setOpen] = useState(false);
7
+ const visible = useRef(false);
8
+ const entry = useRef<string | null>(null);
9
+ const setVisible = useCallback((next: boolean) => {
10
+ visible.current = next;
11
+ setOpen(next);
12
+ if (persist) try { localStorage.setItem("papyrus:console-open", String(next)); } catch { /* Optional preference. */ }
13
+ }, [persist]);
14
+ const openConsole = useCallback(() => {
15
+ if (!available || visible.current) return;
16
+ const existing = history.state?.papyrusMobileChat;
17
+ if (typeof existing === "string") entry.current = existing;
18
+ else if (matchMedia("(max-width: 900px)").matches) {
19
+ entry.current = crypto.randomUUID();
20
+ history.pushState({ ...history.state, papyrusMobileChat: entry.current }, "", location.href);
21
+ }
22
+ setVisible(true);
23
+ }, [available, setVisible]);
24
+ const closeConsole = useCallback(() => {
25
+ if (entry.current && history.state?.papyrusMobileChat === entry.current) history.back();
26
+ else setVisible(false);
27
+ }, [setVisible]);
28
+ const toggleOpen = useCallback(() => {
29
+ if (visible.current) closeConsole();
30
+ else openConsole();
31
+ }, [closeConsole, openConsole]);
32
+ useEffect(() => {
33
+ if (!available) {
34
+ visible.current = false;
35
+ setOpen(false);
36
+ return;
37
+ }
38
+ const pop = (event: PopStateEvent) => {
39
+ if (entry.current) setVisible(event.state?.papyrusMobileChat === entry.current);
40
+ };
41
+ window.addEventListener("popstate", pop);
42
+ if (typeof history.state?.papyrusMobileChat === "string") openConsole();
43
+ else if (persist) try { if (localStorage.getItem("papyrus:console-open") === "true") openConsole(); } catch { /* Optional preference. */ }
44
+ return () => window.removeEventListener("popstate", pop);
45
+ }, [available, openConsole, persist, setVisible]);
46
+ return { open, openConsole, closeConsole, toggleOpen };
47
+ }
package/package.json CHANGED
@@ -106,6 +106,7 @@
106
106
  "./components/newsroom-client-shell": "./components/newsroom-client-shell.tsx",
107
107
  "./components/newsroom-curation-bootstrap": "./components/newsroom-curation-bootstrap.tsx",
108
108
  "./components/newsroom-curation-provider": "./components/newsroom-curation-provider.tsx",
109
+ "./components/newsroom-mobile-navigation": "./components/newsroom-mobile-navigation.tsx",
109
110
  "./components/newsroom-ops-overview": "./components/newsroom-ops-overview.tsx",
110
111
  "./components/newsroom-ops-shell": "./components/newsroom-ops-shell.tsx",
111
112
  "./components/newsroom-overview-skeleton": "./components/newsroom-overview-skeleton.tsx",
@@ -118,6 +119,7 @@
118
119
  "./components/newsroom-topics-view": "./components/newsroom-topics-view.tsx",
119
120
  "./components/notification-center": "./components/notification-center.tsx",
120
121
  "./components/papyrus-console-conversation": "./components/papyrus-console-conversation.tsx",
122
+ "./components/papyrus-console-frame": "./components/papyrus-console-frame.tsx",
121
123
  "./components/papyrus-console-shell": "./components/papyrus-console-shell.tsx",
122
124
  "./components/papyrus-private-chat-panel": "./components/papyrus-private-chat-panel.tsx",
123
125
  "./components/pictogram-figure": "./components/pictogram-figure.tsx",
@@ -167,6 +169,7 @@
167
169
  "./components/ui/tooltip": "./components/ui/tooltip.tsx",
168
170
  "./components/use-blog-header-obstacles": "./components/use-blog-header-obstacles.ts",
169
171
  "./components/use-brand-fonts-ready": "./components/use-brand-fonts-ready.ts",
172
+ "./components/use-console-visibility": "./components/use-console-visibility.ts",
170
173
  "./components/use-editorial-checks": "./components/use-editorial-checks.ts",
171
174
  "./components/use-near-viewport": "./components/use-near-viewport.ts",
172
175
  "./components/use-paged-content-item-versions": "./components/use-paged-content-item-versions.ts",
@@ -458,7 +461,7 @@
458
461
  "optional": true
459
462
  }
460
463
  },
461
- "version": "5.41.2",
464
+ "version": "5.41.4",
462
465
  "dependencies": {
463
466
  "@aws-amplify/adapter-nextjs": "^1.7.3",
464
467
  "@aws-crypto/sha256-js": "5.2.0",
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "5.41.2",
2
+ "version": "5.41.4",
3
3
  "routes": [
4
4
  {
5
5
  "file": "app/%5F_preview/[[...path]]/route.ts",
@@ -50,7 +50,7 @@ export function staticGenerationSettings() {
50
50
  };
51
51
  }
52
52
 
53
- export const DEFAULT_TRANSPILE_PACKAGES = ["@anthusai/papyrus", "cyclotron", "chatticus"];
53
+ export const DEFAULT_TRANSPILE_PACKAGES = ["@anthusai/papyrus", "cyclotron", "chatticus", "lucide-react"];
54
54
 
55
55
  export function mergeTranspilePackages(existing = []) {
56
56
  return [...new Set([...existing, ...DEFAULT_TRANSPILE_PACKAGES])];