@xenide-io/the-old-ui-theme 0.6.9 → 0.6.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/suite.d.mts CHANGED
@@ -477,9 +477,29 @@ declare function SuiteThemeProvider({ config, children, }: {
477
477
  declare function useSuiteTheme(): SuiteThemeContextValue;
478
478
 
479
479
  declare const SUITE_OPEN_ASK_AI_EVENT = "shellstack:open-ask-ai";
480
+ declare const SUITE_ASK_AI_OPEN_KEY = "shellstack:shelly-open";
481
+ declare const SUITE_ASK_AI_OPEN_QUERY = "shelly";
482
+ declare const SUITE_MUTATED_EVENT = "shellstack:suite-mutated";
483
+ declare const TURTLETIME_TIMER_MUTATED_EVENT = "tt-timer-mutated";
480
484
  type SuiteAskAiOpenDetail = {
481
485
  prompt?: string;
482
486
  };
487
+ declare function persistSuiteAskAiOpen(open: boolean): void;
488
+ declare function readSuiteAskAiOpen(): boolean;
489
+ /** Stamp a destination path so the other app opens Shelly after SSO. */
490
+ declare function pathWithSuiteAskAiOpen(path: string): string;
491
+ /** Open Shelly only after a `?shelly=1` handoff — not a leftover session flag. */
492
+ declare function consumeSuiteAskAiOpenFromLocation(): boolean;
493
+ type SuiteAiActionStatus = "proposed" | "applied" | "cancelled" | "failed";
494
+ interface SuiteAiAction {
495
+ id: string;
496
+ kind: string;
497
+ status: SuiteAiActionStatus;
498
+ summary: string;
499
+ href?: string;
500
+ error?: string;
501
+ payload?: Record<string, unknown>;
502
+ }
483
503
  /** Open the suite Ask AI panel from anywhere (Today card, command palette, …). */
484
504
  declare function openSuiteAskAi(detail?: SuiteAskAiOpenDetail): void;
485
505
  /** Consume a prompt queued before the panel mounted. */
@@ -492,12 +512,13 @@ interface SuiteAiChatMessage {
492
512
  role: "user" | "assistant";
493
513
  content: string;
494
514
  created_at?: string;
515
+ actions?: SuiteAiAction[];
495
516
  }
496
517
  /**
497
518
  * Suite-wide Ask AI chat — Notion-style continuous thread.
498
519
  * Lives in the sidebar (or any parent that mounts it). Not Kraken Deep Research.
499
520
  */
500
- declare function SuiteAiPanel({ presets, emptyState, title, fetchChat, sendMessage, clearChat, brandIcon: BrandIcon, spinner: Spinner, open: openProp, onOpenChange, suiteAppBases, onSwitchApp, }: {
521
+ declare function SuiteAiPanel({ presets, emptyState, title, fetchChat, sendMessage, clearChat, brandIcon: BrandIcon, spinner: Spinner, open: openProp, onOpenChange, suiteAppBases, onSwitchApp, onSameAppNavigate, resolveAction, }: {
501
522
  presets?: SuiteAiPreset[];
502
523
  emptyState?: ReactNode;
503
524
  title?: string;
@@ -525,6 +546,11 @@ declare function SuiteAiPanel({ presets, emptyState, title, fetchChat, sendMessa
525
546
  suiteAppBases?: Partial<Record<SuiteAppSlug, string>>;
526
547
  /** Cross-app SSO. Same-app links just navigate to `path`. */
527
548
  onSwitchApp?: (app: SuiteAppSlug, path: string) => void;
549
+ /** Client-side same-app route change — keeps Shelly mounted. */
550
+ onSameAppNavigate?: (path: string) => void;
551
+ resolveAction?: (id: string, decision: "confirm" | "cancel") => Promise<{
552
+ messages: SuiteAiChatMessage[];
553
+ }>;
528
554
  }): react.JSX.Element | null;
529
555
 
530
556
  interface SuiteWorkspaceEntry {
@@ -951,4 +977,4 @@ interface SuiteAppLayoutProps {
951
977
  */
952
978
  declare function SuiteAppLayout({ sidebar, children, mobileHeader, bottomNav, sidebarWidth, collapsed, lockMainScroll, onStartResize, onResizeBy, onResetWidth, className, }: SuiteAppLayoutProps): react.JSX.Element;
953
979
 
954
- export { APP_ACCENTS, APP_GLYPHS, AnimatedMoon, AnimatedSun, AppSwitcher, AppSwitcherChevron, AppSwitcherMark, CommandPaletteHost, DeferredChrome, SIDEBAR_COLLAPSE_THRESHOLD, SIDEBAR_DEFAULT_WIDTH, SIDEBAR_MAX_WIDTH, SIDEBAR_MIN_EXPANDED_WIDTH, SIDEBAR_RAIL_WIDTH, SUITE_APPS, SUITE_APP_MAP, SUITE_GLYPHS, SUITE_ICON_NAMES, SUITE_OPEN_ASK_AI_EVENT, SUITE_SPRINGS, SourceAppGlyph, type SuiteAccentSlug, type SuiteAiChatMessage, SuiteAiPanel, type SuiteAiPreset, type SuiteAppAccent, type SuiteAppDefinition, type SuiteAppEntry, SuiteAppIcon, type SuiteAppIconProps, SuiteAppLayout, type SuiteAppLayoutProps, type SuiteAppSlug, SuiteAppStrip, type SuiteAskAiOpenDetail, SuiteBottomNav, type SuiteBottomNavItem, SuiteBreadcrumbs, type SuiteBreadcrumbsProps, type SuiteCommandItem, type SuiteCommandPaletteComponent, type SuiteDropdownItemComponent, type SuiteDropdownMenuComponent, type SuiteDropdownMenuProps, SuiteEmptyState, type SuiteGlyph, type SuiteGlyphElement, type SuiteHrefTarget, SuiteIcon, type SuiteIconName, type SuiteIconProps, SuiteMobileDrawer, SuiteMobileHeader, SuiteMotionProvider, type SuiteNotification, SuiteNotificationBell, type SuiteNotificationsResponse, SuitePage, SuitePageHeader, type SuitePageWidth, type SuiteResolvedTheme, SuiteSectionHeader, SuiteSettingsLayout, type SuiteSettingsLayoutProps, SuiteSettingsMobileNav, type SuiteSettingsNavItem, SuiteSidebar, type SuiteSidebarNavItem, SuiteSkeleton, SuiteSkeletonCard, SuiteSkeletonList, type SuiteSpinnerComponent, type SuiteSpringName, SuiteTabList, type SuiteTheme, type SuiteThemeConfig, type SuiteThemeContextValue, SuiteThemeProvider, SuiteToolbar, SuiteUserMenu, type SuiteUserMenuProps, type SuiteWorkspaceEntry, type SuiteWorkspaceGroup, SuiteWorkspaceSwitcher, TodayAskAiCard, TodayCalibrating, TodayEmptyAction, TodayEmptyState, TodayHero, TodayLayout, TodayPageFrame, TodayPanel, type TodayPrimaryAccent, TodayPrimaryAction, TodaySection, TodayTimeIcon, TodayTopBar, appSwitcherMarkClass, appSwitcherMenuItemClass, appSwitcherTriggerClass, classifySuiteHref, cn, consumePendingAskAiPrompt, getTodayGreeting, openSuiteAskAi, resolveSuiteNotificationHref, sidebarColumnWidth, sourceToSuiteApp, suiteAppBaseUrl, suiteAppLabel, useIdleMount, useSidebarWidth, useSuiteTheme };
980
+ export { APP_ACCENTS, APP_GLYPHS, AnimatedMoon, AnimatedSun, AppSwitcher, AppSwitcherChevron, AppSwitcherMark, CommandPaletteHost, DeferredChrome, SIDEBAR_COLLAPSE_THRESHOLD, SIDEBAR_DEFAULT_WIDTH, SIDEBAR_MAX_WIDTH, SIDEBAR_MIN_EXPANDED_WIDTH, SIDEBAR_RAIL_WIDTH, SUITE_APPS, SUITE_APP_MAP, SUITE_ASK_AI_OPEN_KEY, SUITE_ASK_AI_OPEN_QUERY, SUITE_GLYPHS, SUITE_ICON_NAMES, SUITE_MUTATED_EVENT, SUITE_OPEN_ASK_AI_EVENT, SUITE_SPRINGS, SourceAppGlyph, type SuiteAccentSlug, type SuiteAiAction, type SuiteAiActionStatus, type SuiteAiChatMessage, SuiteAiPanel, type SuiteAiPreset, type SuiteAppAccent, type SuiteAppDefinition, type SuiteAppEntry, SuiteAppIcon, type SuiteAppIconProps, SuiteAppLayout, type SuiteAppLayoutProps, type SuiteAppSlug, SuiteAppStrip, type SuiteAskAiOpenDetail, SuiteBottomNav, type SuiteBottomNavItem, SuiteBreadcrumbs, type SuiteBreadcrumbsProps, type SuiteCommandItem, type SuiteCommandPaletteComponent, type SuiteDropdownItemComponent, type SuiteDropdownMenuComponent, type SuiteDropdownMenuProps, SuiteEmptyState, type SuiteGlyph, type SuiteGlyphElement, type SuiteHrefTarget, SuiteIcon, type SuiteIconName, type SuiteIconProps, SuiteMobileDrawer, SuiteMobileHeader, SuiteMotionProvider, type SuiteNotification, SuiteNotificationBell, type SuiteNotificationsResponse, SuitePage, SuitePageHeader, type SuitePageWidth, type SuiteResolvedTheme, SuiteSectionHeader, SuiteSettingsLayout, type SuiteSettingsLayoutProps, SuiteSettingsMobileNav, type SuiteSettingsNavItem, SuiteSidebar, type SuiteSidebarNavItem, SuiteSkeleton, SuiteSkeletonCard, SuiteSkeletonList, type SuiteSpinnerComponent, type SuiteSpringName, SuiteTabList, type SuiteTheme, type SuiteThemeConfig, type SuiteThemeContextValue, SuiteThemeProvider, SuiteToolbar, SuiteUserMenu, type SuiteUserMenuProps, type SuiteWorkspaceEntry, type SuiteWorkspaceGroup, SuiteWorkspaceSwitcher, TURTLETIME_TIMER_MUTATED_EVENT, TodayAskAiCard, TodayCalibrating, TodayEmptyAction, TodayEmptyState, TodayHero, TodayLayout, TodayPageFrame, TodayPanel, type TodayPrimaryAccent, TodayPrimaryAction, TodaySection, TodayTimeIcon, TodayTopBar, appSwitcherMarkClass, appSwitcherMenuItemClass, appSwitcherTriggerClass, classifySuiteHref, cn, consumePendingAskAiPrompt, consumeSuiteAskAiOpenFromLocation, getTodayGreeting, openSuiteAskAi, pathWithSuiteAskAiOpen, persistSuiteAskAiOpen, readSuiteAskAiOpen, resolveSuiteNotificationHref, sidebarColumnWidth, sourceToSuiteApp, suiteAppBaseUrl, suiteAppLabel, useIdleMount, useSidebarWidth, useSuiteTheme };
package/dist/suite.d.ts CHANGED
@@ -477,9 +477,29 @@ declare function SuiteThemeProvider({ config, children, }: {
477
477
  declare function useSuiteTheme(): SuiteThemeContextValue;
478
478
 
479
479
  declare const SUITE_OPEN_ASK_AI_EVENT = "shellstack:open-ask-ai";
480
+ declare const SUITE_ASK_AI_OPEN_KEY = "shellstack:shelly-open";
481
+ declare const SUITE_ASK_AI_OPEN_QUERY = "shelly";
482
+ declare const SUITE_MUTATED_EVENT = "shellstack:suite-mutated";
483
+ declare const TURTLETIME_TIMER_MUTATED_EVENT = "tt-timer-mutated";
480
484
  type SuiteAskAiOpenDetail = {
481
485
  prompt?: string;
482
486
  };
487
+ declare function persistSuiteAskAiOpen(open: boolean): void;
488
+ declare function readSuiteAskAiOpen(): boolean;
489
+ /** Stamp a destination path so the other app opens Shelly after SSO. */
490
+ declare function pathWithSuiteAskAiOpen(path: string): string;
491
+ /** Open Shelly only after a `?shelly=1` handoff — not a leftover session flag. */
492
+ declare function consumeSuiteAskAiOpenFromLocation(): boolean;
493
+ type SuiteAiActionStatus = "proposed" | "applied" | "cancelled" | "failed";
494
+ interface SuiteAiAction {
495
+ id: string;
496
+ kind: string;
497
+ status: SuiteAiActionStatus;
498
+ summary: string;
499
+ href?: string;
500
+ error?: string;
501
+ payload?: Record<string, unknown>;
502
+ }
483
503
  /** Open the suite Ask AI panel from anywhere (Today card, command palette, …). */
484
504
  declare function openSuiteAskAi(detail?: SuiteAskAiOpenDetail): void;
485
505
  /** Consume a prompt queued before the panel mounted. */
@@ -492,12 +512,13 @@ interface SuiteAiChatMessage {
492
512
  role: "user" | "assistant";
493
513
  content: string;
494
514
  created_at?: string;
515
+ actions?: SuiteAiAction[];
495
516
  }
496
517
  /**
497
518
  * Suite-wide Ask AI chat — Notion-style continuous thread.
498
519
  * Lives in the sidebar (or any parent that mounts it). Not Kraken Deep Research.
499
520
  */
500
- declare function SuiteAiPanel({ presets, emptyState, title, fetchChat, sendMessage, clearChat, brandIcon: BrandIcon, spinner: Spinner, open: openProp, onOpenChange, suiteAppBases, onSwitchApp, }: {
521
+ declare function SuiteAiPanel({ presets, emptyState, title, fetchChat, sendMessage, clearChat, brandIcon: BrandIcon, spinner: Spinner, open: openProp, onOpenChange, suiteAppBases, onSwitchApp, onSameAppNavigate, resolveAction, }: {
501
522
  presets?: SuiteAiPreset[];
502
523
  emptyState?: ReactNode;
503
524
  title?: string;
@@ -525,6 +546,11 @@ declare function SuiteAiPanel({ presets, emptyState, title, fetchChat, sendMessa
525
546
  suiteAppBases?: Partial<Record<SuiteAppSlug, string>>;
526
547
  /** Cross-app SSO. Same-app links just navigate to `path`. */
527
548
  onSwitchApp?: (app: SuiteAppSlug, path: string) => void;
549
+ /** Client-side same-app route change — keeps Shelly mounted. */
550
+ onSameAppNavigate?: (path: string) => void;
551
+ resolveAction?: (id: string, decision: "confirm" | "cancel") => Promise<{
552
+ messages: SuiteAiChatMessage[];
553
+ }>;
528
554
  }): react.JSX.Element | null;
529
555
 
530
556
  interface SuiteWorkspaceEntry {
@@ -951,4 +977,4 @@ interface SuiteAppLayoutProps {
951
977
  */
952
978
  declare function SuiteAppLayout({ sidebar, children, mobileHeader, bottomNav, sidebarWidth, collapsed, lockMainScroll, onStartResize, onResizeBy, onResetWidth, className, }: SuiteAppLayoutProps): react.JSX.Element;
953
979
 
954
- export { APP_ACCENTS, APP_GLYPHS, AnimatedMoon, AnimatedSun, AppSwitcher, AppSwitcherChevron, AppSwitcherMark, CommandPaletteHost, DeferredChrome, SIDEBAR_COLLAPSE_THRESHOLD, SIDEBAR_DEFAULT_WIDTH, SIDEBAR_MAX_WIDTH, SIDEBAR_MIN_EXPANDED_WIDTH, SIDEBAR_RAIL_WIDTH, SUITE_APPS, SUITE_APP_MAP, SUITE_GLYPHS, SUITE_ICON_NAMES, SUITE_OPEN_ASK_AI_EVENT, SUITE_SPRINGS, SourceAppGlyph, type SuiteAccentSlug, type SuiteAiChatMessage, SuiteAiPanel, type SuiteAiPreset, type SuiteAppAccent, type SuiteAppDefinition, type SuiteAppEntry, SuiteAppIcon, type SuiteAppIconProps, SuiteAppLayout, type SuiteAppLayoutProps, type SuiteAppSlug, SuiteAppStrip, type SuiteAskAiOpenDetail, SuiteBottomNav, type SuiteBottomNavItem, SuiteBreadcrumbs, type SuiteBreadcrumbsProps, type SuiteCommandItem, type SuiteCommandPaletteComponent, type SuiteDropdownItemComponent, type SuiteDropdownMenuComponent, type SuiteDropdownMenuProps, SuiteEmptyState, type SuiteGlyph, type SuiteGlyphElement, type SuiteHrefTarget, SuiteIcon, type SuiteIconName, type SuiteIconProps, SuiteMobileDrawer, SuiteMobileHeader, SuiteMotionProvider, type SuiteNotification, SuiteNotificationBell, type SuiteNotificationsResponse, SuitePage, SuitePageHeader, type SuitePageWidth, type SuiteResolvedTheme, SuiteSectionHeader, SuiteSettingsLayout, type SuiteSettingsLayoutProps, SuiteSettingsMobileNav, type SuiteSettingsNavItem, SuiteSidebar, type SuiteSidebarNavItem, SuiteSkeleton, SuiteSkeletonCard, SuiteSkeletonList, type SuiteSpinnerComponent, type SuiteSpringName, SuiteTabList, type SuiteTheme, type SuiteThemeConfig, type SuiteThemeContextValue, SuiteThemeProvider, SuiteToolbar, SuiteUserMenu, type SuiteUserMenuProps, type SuiteWorkspaceEntry, type SuiteWorkspaceGroup, SuiteWorkspaceSwitcher, TodayAskAiCard, TodayCalibrating, TodayEmptyAction, TodayEmptyState, TodayHero, TodayLayout, TodayPageFrame, TodayPanel, type TodayPrimaryAccent, TodayPrimaryAction, TodaySection, TodayTimeIcon, TodayTopBar, appSwitcherMarkClass, appSwitcherMenuItemClass, appSwitcherTriggerClass, classifySuiteHref, cn, consumePendingAskAiPrompt, getTodayGreeting, openSuiteAskAi, resolveSuiteNotificationHref, sidebarColumnWidth, sourceToSuiteApp, suiteAppBaseUrl, suiteAppLabel, useIdleMount, useSidebarWidth, useSuiteTheme };
980
+ export { APP_ACCENTS, APP_GLYPHS, AnimatedMoon, AnimatedSun, AppSwitcher, AppSwitcherChevron, AppSwitcherMark, CommandPaletteHost, DeferredChrome, SIDEBAR_COLLAPSE_THRESHOLD, SIDEBAR_DEFAULT_WIDTH, SIDEBAR_MAX_WIDTH, SIDEBAR_MIN_EXPANDED_WIDTH, SIDEBAR_RAIL_WIDTH, SUITE_APPS, SUITE_APP_MAP, SUITE_ASK_AI_OPEN_KEY, SUITE_ASK_AI_OPEN_QUERY, SUITE_GLYPHS, SUITE_ICON_NAMES, SUITE_MUTATED_EVENT, SUITE_OPEN_ASK_AI_EVENT, SUITE_SPRINGS, SourceAppGlyph, type SuiteAccentSlug, type SuiteAiAction, type SuiteAiActionStatus, type SuiteAiChatMessage, SuiteAiPanel, type SuiteAiPreset, type SuiteAppAccent, type SuiteAppDefinition, type SuiteAppEntry, SuiteAppIcon, type SuiteAppIconProps, SuiteAppLayout, type SuiteAppLayoutProps, type SuiteAppSlug, SuiteAppStrip, type SuiteAskAiOpenDetail, SuiteBottomNav, type SuiteBottomNavItem, SuiteBreadcrumbs, type SuiteBreadcrumbsProps, type SuiteCommandItem, type SuiteCommandPaletteComponent, type SuiteDropdownItemComponent, type SuiteDropdownMenuComponent, type SuiteDropdownMenuProps, SuiteEmptyState, type SuiteGlyph, type SuiteGlyphElement, type SuiteHrefTarget, SuiteIcon, type SuiteIconName, type SuiteIconProps, SuiteMobileDrawer, SuiteMobileHeader, SuiteMotionProvider, type SuiteNotification, SuiteNotificationBell, type SuiteNotificationsResponse, SuitePage, SuitePageHeader, type SuitePageWidth, type SuiteResolvedTheme, SuiteSectionHeader, SuiteSettingsLayout, type SuiteSettingsLayoutProps, SuiteSettingsMobileNav, type SuiteSettingsNavItem, SuiteSidebar, type SuiteSidebarNavItem, SuiteSkeleton, SuiteSkeletonCard, SuiteSkeletonList, type SuiteSpinnerComponent, type SuiteSpringName, SuiteTabList, type SuiteTheme, type SuiteThemeConfig, type SuiteThemeContextValue, SuiteThemeProvider, SuiteToolbar, SuiteUserMenu, type SuiteUserMenuProps, type SuiteWorkspaceEntry, type SuiteWorkspaceGroup, SuiteWorkspaceSwitcher, TURTLETIME_TIMER_MUTATED_EVENT, TodayAskAiCard, TodayCalibrating, TodayEmptyAction, TodayEmptyState, TodayHero, TodayLayout, TodayPageFrame, TodayPanel, type TodayPrimaryAccent, TodayPrimaryAction, TodaySection, TodayTimeIcon, TodayTopBar, appSwitcherMarkClass, appSwitcherMenuItemClass, appSwitcherTriggerClass, classifySuiteHref, cn, consumePendingAskAiPrompt, consumeSuiteAskAiOpenFromLocation, getTodayGreeting, openSuiteAskAi, pathWithSuiteAskAiOpen, persistSuiteAskAiOpen, readSuiteAskAiOpen, resolveSuiteNotificationHref, sidebarColumnWidth, sourceToSuiteApp, suiteAppBaseUrl, suiteAppLabel, useIdleMount, useSidebarWidth, useSuiteTheme };
package/dist/suite.js CHANGED
@@ -243,8 +243,11 @@ __export(suite_exports, {
243
243
  SIDEBAR_RAIL_WIDTH: () => SIDEBAR_RAIL_WIDTH,
244
244
  SUITE_APPS: () => SUITE_APPS2,
245
245
  SUITE_APP_MAP: () => SUITE_APP_MAP,
246
+ SUITE_ASK_AI_OPEN_KEY: () => SUITE_ASK_AI_OPEN_KEY,
247
+ SUITE_ASK_AI_OPEN_QUERY: () => SUITE_ASK_AI_OPEN_QUERY,
246
248
  SUITE_GLYPHS: () => SUITE_GLYPHS,
247
249
  SUITE_ICON_NAMES: () => SUITE_ICON_NAMES,
250
+ SUITE_MUTATED_EVENT: () => SUITE_MUTATED_EVENT,
248
251
  SUITE_OPEN_ASK_AI_EVENT: () => SUITE_OPEN_ASK_AI_EVENT,
249
252
  SUITE_SPRINGS: () => SUITE_SPRINGS,
250
253
  SourceAppGlyph: () => SourceAppGlyph,
@@ -274,6 +277,7 @@ __export(suite_exports, {
274
277
  SuiteToolbar: () => SuiteToolbar,
275
278
  SuiteUserMenu: () => SuiteUserMenu,
276
279
  SuiteWorkspaceSwitcher: () => SuiteWorkspaceSwitcher,
280
+ TURTLETIME_TIMER_MUTATED_EVENT: () => TURTLETIME_TIMER_MUTATED_EVENT,
277
281
  TodayAskAiCard: () => TodayAskAiCard,
278
282
  TodayCalibrating: () => TodayCalibrating,
279
283
  TodayEmptyAction: () => TodayEmptyAction,
@@ -292,9 +296,13 @@ __export(suite_exports, {
292
296
  classifySuiteHref: () => classifySuiteHref,
293
297
  cn: () => cn,
294
298
  consumePendingAskAiPrompt: () => consumePendingAskAiPrompt,
299
+ consumeSuiteAskAiOpenFromLocation: () => consumeSuiteAskAiOpenFromLocation,
295
300
  getTodayGreeting: () => getTodayGreeting,
296
301
  m: () => import_react14.m,
297
302
  openSuiteAskAi: () => openSuiteAskAi,
303
+ pathWithSuiteAskAiOpen: () => pathWithSuiteAskAiOpen,
304
+ persistSuiteAskAiOpen: () => persistSuiteAskAiOpen,
305
+ readSuiteAskAiOpen: () => readSuiteAskAiOpen,
298
306
  resolveSuiteNotificationHref: () => resolveSuiteNotificationHref,
299
307
  sidebarColumnWidth: () => sidebarColumnWidth,
300
308
  sourceToSuiteApp: () => sourceToSuiteApp,
@@ -1802,7 +1810,7 @@ function SuiteMobileDrawer({
1802
1810
  tabIndex: -1,
1803
1811
  "data-test": panelDataTest,
1804
1812
  className: cn(
1805
- "suite-scroll-lock relative flex h-full w-[86%] max-w-72 flex-col overflow-hidden bg-ph-surface shadow-xl outline-none motion-safe:transition-transform motion-safe:ease-spring-fast",
1813
+ "relative flex h-dvh max-h-dvh w-[86%] max-w-72 flex-col overflow-hidden bg-ph-surface shadow-xl outline-none motion-safe:transition-transform motion-safe:ease-spring-fast",
1806
1814
  side === "right" && "ml-auto",
1807
1815
  shown ? "translate-x-0" : side === "right" ? "translate-x-full" : "-translate-x-full",
1808
1816
  panelClassName
@@ -1833,7 +1841,14 @@ function SuiteMobileDrawer({
1833
1841
  ]
1834
1842
  }
1835
1843
  ) : null,
1836
- children
1844
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1845
+ "div",
1846
+ {
1847
+ "data-test": "suite-mobile-drawer-body",
1848
+ className: "suite-scroll-lock flex min-h-0 flex-1 flex-col overflow-y-auto overscroll-contain pb-[max(0.75rem,env(safe-area-inset-bottom))]",
1849
+ children
1850
+ }
1851
+ )
1837
1852
  ]
1838
1853
  }
1839
1854
  )
@@ -2736,6 +2751,44 @@ function Tooltip({
2736
2751
  var import_jsx_runtime21 = require("react/jsx-runtime");
2737
2752
  var SuiteAiBlockNoteMessage2 = (0, import_react11.lazy)(() => Promise.resolve().then(() => (init_ai_message_blocknote(), ai_message_blocknote_exports)));
2738
2753
  var SUITE_OPEN_ASK_AI_EVENT = "shellstack:open-ask-ai";
2754
+ var SUITE_ASK_AI_OPEN_KEY = "shellstack:shelly-open";
2755
+ var SUITE_ASK_AI_OPEN_QUERY = "shelly";
2756
+ var SUITE_MUTATED_EVENT = "shellstack:suite-mutated";
2757
+ var TURTLETIME_TIMER_MUTATED_EVENT = "tt-timer-mutated";
2758
+ function persistSuiteAskAiOpen(open) {
2759
+ if (typeof window === "undefined") return;
2760
+ try {
2761
+ if (open) sessionStorage.setItem(SUITE_ASK_AI_OPEN_KEY, "1");
2762
+ else sessionStorage.removeItem(SUITE_ASK_AI_OPEN_KEY);
2763
+ } catch (e) {
2764
+ }
2765
+ }
2766
+ function readSuiteAskAiOpen() {
2767
+ if (typeof window === "undefined") return false;
2768
+ try {
2769
+ return sessionStorage.getItem(SUITE_ASK_AI_OPEN_KEY) === "1";
2770
+ } catch (e) {
2771
+ return false;
2772
+ }
2773
+ }
2774
+ function pathWithSuiteAskAiOpen(path) {
2775
+ const url = new URL((path || "/").trim() || "/", "http://local.invalid");
2776
+ url.searchParams.set(SUITE_ASK_AI_OPEN_QUERY, "1");
2777
+ return `${url.pathname}${url.search}${url.hash}`;
2778
+ }
2779
+ function consumeSuiteAskAiOpenFromLocation() {
2780
+ if (typeof window === "undefined") return false;
2781
+ const url = new URL(window.location.href);
2782
+ if (url.searchParams.get(SUITE_ASK_AI_OPEN_QUERY) !== "1") return false;
2783
+ persistSuiteAskAiOpen(true);
2784
+ url.searchParams.delete(SUITE_ASK_AI_OPEN_QUERY);
2785
+ window.history.replaceState(
2786
+ window.history.state,
2787
+ "",
2788
+ `${url.pathname}${url.search}${url.hash}`
2789
+ );
2790
+ return true;
2791
+ }
2739
2792
  var pendingAskAiPrompt = null;
2740
2793
  function openSuiteAskAi(detail) {
2741
2794
  var _a;
@@ -2752,6 +2805,18 @@ function consumePendingAskAiPrompt() {
2752
2805
  pendingAskAiPrompt = null;
2753
2806
  return next;
2754
2807
  }
2808
+ function notifySuiteMutated(actions) {
2809
+ if (typeof window === "undefined" || !(actions == null ? void 0 : actions.length)) return;
2810
+ const kinds = actions.map((action) => action.kind);
2811
+ if (kinds.some(
2812
+ (kind) => kind.includes("timer") || kind.includes("time") || kind.includes("hours")
2813
+ )) {
2814
+ window.dispatchEvent(new Event(TURTLETIME_TIMER_MUTATED_EVENT));
2815
+ }
2816
+ window.dispatchEvent(
2817
+ new CustomEvent(SUITE_MUTATED_EVENT, { detail: { kinds } })
2818
+ );
2819
+ }
2755
2820
  function SuiteAiPanel({
2756
2821
  presets = [],
2757
2822
  emptyState = "Ask when you are ready \u2014 overdue work, a running timer, or anything else.",
@@ -2764,13 +2829,17 @@ function SuiteAiPanel({
2764
2829
  open: openProp,
2765
2830
  onOpenChange,
2766
2831
  suiteAppBases,
2767
- onSwitchApp
2832
+ onSwitchApp,
2833
+ onSameAppNavigate,
2834
+ resolveAction
2768
2835
  }) {
2769
2836
  const inputId = (0, import_react11.useId)();
2770
2837
  const [uncontrolledOpen, setUncontrolledOpen] = (0, import_react11.useState)(false);
2838
+ const [resolvingId, setResolvingId] = (0, import_react11.useState)("");
2771
2839
  const open = openProp != null ? openProp : uncontrolledOpen;
2772
2840
  const setOpen = (0, import_react11.useCallback)(
2773
2841
  (next) => {
2842
+ persistSuiteAskAiOpen(next);
2774
2843
  if (openProp === void 0) setUncontrolledOpen(next);
2775
2844
  onOpenChange == null ? void 0 : onOpenChange(next);
2776
2845
  },
@@ -2871,7 +2940,14 @@ function SuiteAiPanel({
2871
2940
  signal: controller.signal
2872
2941
  });
2873
2942
  if (controller.signal.aborted) return;
2874
- setMessages((_a = result.messages) != null ? _a : []);
2943
+ const nextMessages = (_a = result.messages) != null ? _a : [];
2944
+ setMessages(nextMessages);
2945
+ notifySuiteMutated(
2946
+ nextMessages.flatMap((message) => {
2947
+ var _a2;
2948
+ return (_a2 = message.actions) != null ? _a2 : [];
2949
+ })
2950
+ );
2875
2951
  } catch (err) {
2876
2952
  if (controller.signal.aborted) return;
2877
2953
  setMessages(
@@ -2914,6 +2990,29 @@ function SuiteAiPanel({
2914
2990
  );
2915
2991
  }
2916
2992
  }
2993
+ async function handleResolve(actionId, decision) {
2994
+ var _a;
2995
+ if (!resolveAction || resolvingId) return;
2996
+ setResolvingId(actionId);
2997
+ setError("");
2998
+ try {
2999
+ const result = await resolveAction(actionId, decision);
3000
+ const nextMessages = (_a = result.messages) != null ? _a : [];
3001
+ setMessages(nextMessages);
3002
+ notifySuiteMutated(
3003
+ nextMessages.flatMap((message) => {
3004
+ var _a2;
3005
+ return (_a2 = message.actions) != null ? _a2 : [];
3006
+ })
3007
+ );
3008
+ } catch (err) {
3009
+ setError(
3010
+ err instanceof Error ? err.message : "Could not apply that action."
3011
+ );
3012
+ } finally {
3013
+ setResolvingId("");
3014
+ }
3015
+ }
2917
3016
  function onConversationClick(event) {
2918
3017
  var _a;
2919
3018
  if (event.defaultPrevented) return;
@@ -2931,12 +3030,15 @@ function SuiteAiPanel({
2931
3030
  );
2932
3031
  if (!match) return;
2933
3032
  event.preventDefault();
3033
+ persistSuiteAskAiOpen(true);
2934
3034
  if (match.sameApp) {
2935
- window.location.assign(match.path);
3035
+ if (onSameAppNavigate) onSameAppNavigate(match.path);
3036
+ else window.location.assign(pathWithSuiteAskAiOpen(match.path));
2936
3037
  return;
2937
3038
  }
2938
- if (onSwitchApp) onSwitchApp(match.slug, match.path);
2939
- else window.location.assign(anchor.href);
3039
+ const openPath = pathWithSuiteAskAiOpen(match.path);
3040
+ if (onSwitchApp) onSwitchApp(match.slug, openPath);
3041
+ else window.location.assign(new URL(openPath, href).toString());
2940
3042
  }
2941
3043
  if (!open) return null;
2942
3044
  const Icon = BrandIcon != null ? BrandIcon : import_iconoir_react8.Sparks;
@@ -3001,6 +3103,7 @@ function SuiteAiPanel({
3001
3103
  )) }) : null
3002
3104
  ] }) : null,
3003
3105
  messages.map((message, index) => {
3106
+ var _a;
3004
3107
  const isUser = message.role === "user";
3005
3108
  if (isUser) {
3006
3109
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
@@ -3027,13 +3130,67 @@ function SuiteAiPanel({
3027
3130
  children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, { className: "h-3.5 w-3.5" })
3028
3131
  }
3029
3132
  ),
3030
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "min-w-0 max-w-[85%] rounded-2xl rounded-bl-md bg-ph-muted px-3 py-2 text-sm leading-relaxed text-ph-ink", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3031
- import_react11.Suspense,
3032
- {
3033
- fallback: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "whitespace-pre-wrap break-words", children: message.content }),
3034
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SuiteAiBlockNoteMessage2, { markdown: message.content })
3035
- }
3036
- ) })
3133
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "min-w-0 max-w-[85%] space-y-2", children: [
3134
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "rounded-2xl rounded-bl-md bg-ph-muted px-3 py-2 text-sm leading-relaxed text-ph-ink", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3135
+ import_react11.Suspense,
3136
+ {
3137
+ fallback: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "whitespace-pre-wrap break-words", children: message.content }),
3138
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SuiteAiBlockNoteMessage2, { markdown: message.content })
3139
+ }
3140
+ ) }),
3141
+ ((_a = message.actions) != null ? _a : []).map((action) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
3142
+ "div",
3143
+ {
3144
+ "data-test": "ask-ai-action",
3145
+ "data-status": action.status,
3146
+ className: "rounded-xl border border-ph-border bg-ph-surface px-3 py-2 text-sm text-ph-ink",
3147
+ children: [
3148
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "font-medium", children: action.summary }),
3149
+ action.status === "proposed" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "mt-2 flex flex-wrap gap-2", children: [
3150
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3151
+ "button",
3152
+ {
3153
+ type: "button",
3154
+ "data-test": "ask-ai-action-confirm",
3155
+ disabled: Boolean(resolvingId) || !resolveAction,
3156
+ onClick: () => void handleResolve(action.id, "confirm"),
3157
+ className: "inline-flex min-h-8 items-center rounded-lg bg-ph-brand px-2.5 text-xs font-medium text-[color:var(--ph-on-accent)] transition-opacity hover:bg-ph-brand-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ph-focus disabled:opacity-40",
3158
+ children: resolvingId === action.id ? "Working\u2026" : "Confirm"
3159
+ }
3160
+ ),
3161
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3162
+ "button",
3163
+ {
3164
+ type: "button",
3165
+ "data-test": "ask-ai-action-cancel",
3166
+ disabled: Boolean(resolvingId) || !resolveAction,
3167
+ onClick: () => void handleResolve(action.id, "cancel"),
3168
+ className: "inline-flex min-h-8 items-center rounded-lg border border-ph-border bg-ph-surface px-2.5 text-xs font-medium text-ph-ink transition-colors hover:bg-ph-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ph-focus disabled:opacity-40",
3169
+ children: "Cancel"
3170
+ }
3171
+ )
3172
+ ] }) : null,
3173
+ action.status === "applied" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("p", { className: "mt-1 text-xs text-ph-subtle", children: [
3174
+ "Done",
3175
+ action.href ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
3176
+ " \xB7 ",
3177
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3178
+ "a",
3179
+ {
3180
+ href: action.href,
3181
+ className: "text-ph-brand underline-offset-2 hover:underline",
3182
+ children: "Open"
3183
+ }
3184
+ )
3185
+ ] }) : null
3186
+ ] }) : null,
3187
+ action.status === "cancelled" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "mt-1 text-xs text-ph-subtle", children: "Cancelled" }) : null,
3188
+ action.status === "failed" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "mt-1 text-xs text-ph-danger", children: action.error || "Could not apply that." }) : null
3189
+ ]
3190
+ },
3191
+ action.id
3192
+ ))
3193
+ ] })
3037
3194
  ]
3038
3195
  },
3039
3196
  `assistant-${index}`
@@ -3587,30 +3744,37 @@ function SuiteSidebar({
3587
3744
  }) {
3588
3745
  const showAskAi = Boolean(onAskAiOpenChange && askAi);
3589
3746
  const chatOpen = showAskAi && askAiOpen && !collapsed;
3747
+ const setAskAi = (0, import_react16.useCallback)(
3748
+ (next) => {
3749
+ persistSuiteAskAiOpen(next);
3750
+ onAskAiOpenChange == null ? void 0 : onAskAiOpenChange(next);
3751
+ },
3752
+ [onAskAiOpenChange]
3753
+ );
3590
3754
  (0, import_react16.useEffect)(() => {
3591
3755
  if (!onAskAiOpenChange) return;
3592
3756
  function onOpen() {
3593
3757
  onRequestExpand == null ? void 0 : onRequestExpand();
3594
- onAskAiOpenChange == null ? void 0 : onAskAiOpenChange(true);
3758
+ setAskAi(true);
3595
3759
  }
3596
3760
  window.addEventListener(SUITE_OPEN_ASK_AI_EVENT, onOpen);
3597
3761
  return () => window.removeEventListener(SUITE_OPEN_ASK_AI_EVENT, onOpen);
3598
- }, [onAskAiOpenChange, onRequestExpand]);
3762
+ }, [onAskAiOpenChange, onRequestExpand, setAskAi]);
3599
3763
  (0, import_react16.useEffect)(() => {
3600
3764
  if (!chatOpen) return;
3601
3765
  function onKey(event) {
3602
- if (event.key === "Escape") onAskAiOpenChange == null ? void 0 : onAskAiOpenChange(false);
3766
+ if (event.key === "Escape") setAskAi(false);
3603
3767
  }
3604
3768
  window.addEventListener("keydown", onKey);
3605
3769
  return () => window.removeEventListener("keydown", onKey);
3606
- }, [chatOpen, onAskAiOpenChange]);
3770
+ }, [chatOpen, setAskAi]);
3607
3771
  function toggleAskAi() {
3608
3772
  if (askAiOpen) {
3609
- onAskAiOpenChange == null ? void 0 : onAskAiOpenChange(false);
3773
+ setAskAi(false);
3610
3774
  return;
3611
3775
  }
3612
3776
  if (collapsed) onRequestExpand == null ? void 0 : onRequestExpand();
3613
- onAskAiOpenChange == null ? void 0 : onAskAiOpenChange(true);
3777
+ setAskAi(true);
3614
3778
  }
3615
3779
  const askAiButton = /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
3616
3780
  "button",
@@ -3652,7 +3816,7 @@ function SuiteSidebar({
3652
3816
  type: "button",
3653
3817
  "data-test": "suite-ask-ai-back",
3654
3818
  "aria-label": "Back to navigation",
3655
- onClick: () => onAskAiOpenChange == null ? void 0 : onAskAiOpenChange(false),
3819
+ onClick: () => setAskAi(false),
3656
3820
  className: "inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-lg text-ph-subtle transition-colors hover:bg-ph-muted hover:text-ph-ink focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ph-brand",
3657
3821
  children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_iconoir_react10.NavArrowLeft, { className: "h-4 w-4", "aria-hidden": true })
3658
3822
  }
@@ -3707,7 +3871,7 @@ function SuiteSidebar({
3707
3871
  {
3708
3872
  type: "button",
3709
3873
  "data-test": "suite-ask-ai-back",
3710
- onClick: () => onAskAiOpenChange == null ? void 0 : onAskAiOpenChange(false),
3874
+ onClick: () => setAskAi(false),
3711
3875
  className: "inline-flex h-9 items-center gap-1 rounded-lg px-2 text-sm font-medium text-ph-subtle transition-colors hover:bg-ph-muted hover:text-ph-ink focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ph-brand",
3712
3876
  children: [
3713
3877
  /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_iconoir_react10.NavArrowLeft, { className: "h-4 w-4", "aria-hidden": true }),
@@ -3772,14 +3936,7 @@ function SuiteSidebar({
3772
3936
  );
3773
3937
  return collapsed ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Tooltip, { content: item.label, side: "right", children: link }, item.label) : link;
3774
3938
  }) }) }),
3775
- secondaryNav ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
3776
- "div",
3777
- {
3778
- className: "min-h-0 flex-1",
3779
- "data-test": "suite-sidebar-secondary-nav",
3780
- children: secondaryNav
3781
- }
3782
- ) : null
3939
+ secondaryNav ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "shrink-0", "data-test": "suite-sidebar-secondary-nav", children: secondaryNav }) : null
3783
3940
  ] })
3784
3941
  ]
3785
3942
  }
@@ -3919,8 +4076,11 @@ function SuiteAppLayout({
3919
4076
  SIDEBAR_RAIL_WIDTH,
3920
4077
  SUITE_APPS,
3921
4078
  SUITE_APP_MAP,
4079
+ SUITE_ASK_AI_OPEN_KEY,
4080
+ SUITE_ASK_AI_OPEN_QUERY,
3922
4081
  SUITE_GLYPHS,
3923
4082
  SUITE_ICON_NAMES,
4083
+ SUITE_MUTATED_EVENT,
3924
4084
  SUITE_OPEN_ASK_AI_EVENT,
3925
4085
  SUITE_SPRINGS,
3926
4086
  SourceAppGlyph,
@@ -3950,6 +4110,7 @@ function SuiteAppLayout({
3950
4110
  SuiteToolbar,
3951
4111
  SuiteUserMenu,
3952
4112
  SuiteWorkspaceSwitcher,
4113
+ TURTLETIME_TIMER_MUTATED_EVENT,
3953
4114
  TodayAskAiCard,
3954
4115
  TodayCalibrating,
3955
4116
  TodayEmptyAction,
@@ -3968,9 +4129,13 @@ function SuiteAppLayout({
3968
4129
  classifySuiteHref,
3969
4130
  cn,
3970
4131
  consumePendingAskAiPrompt,
4132
+ consumeSuiteAskAiOpenFromLocation,
3971
4133
  getTodayGreeting,
3972
4134
  m,
3973
4135
  openSuiteAskAi,
4136
+ pathWithSuiteAskAiOpen,
4137
+ persistSuiteAskAiOpen,
4138
+ readSuiteAskAiOpen,
3974
4139
  resolveSuiteNotificationHref,
3975
4140
  sidebarColumnWidth,
3976
4141
  sourceToSuiteApp,