@@ -9,9 +9,12 @@ import { GestureHandlerRootView } from "react-native-gesture-handler";
99import { KeyboardProvider } from "react-native-keyboard-controller" ;
1010import { SafeAreaProvider } from "react-native-safe-area-context" ;
1111import {
12+ CommonActions ,
13+ createPathConfigForStaticNavigation ,
1214 createStaticNavigation ,
1315 getActionFromState ,
1416 getStateFromPath ,
17+ type NavigationAction ,
1518 type NavigationState ,
1619} from "@react-navigation/native" ;
1720
@@ -28,12 +31,20 @@ import {
2831 presentPendingIncomingShare ,
2932 startIncomingShareInbox ,
3033} from "./features/sharing/IncomingShareProvider" ;
34+ import {
35+ installAgentNotificationNavigation ,
36+ setAgentNotificationPathname ,
37+ } from "./features/agent-awareness/notificationNavigation" ;
38+ import {
39+ installAppShortcuts ,
40+ recordAppShortcutNavigationState ,
41+ } from "./features/shortcuts/appShortcutsRuntime" ;
3142import {
3243 AppearancePreferencesProvider ,
3344 installAppearanceRuntime ,
3445 useAppearancePreferences ,
3546} from "./features/settings/appearance/AppearancePreferencesProvider" ;
36- import { RootStack } from "./Stack" ;
47+ import { RootStack , workspaceLocationFromState } from "./Stack" ;
3748import { appAtomRegistry } from "./state/atom-registry" ;
3849import { subscribeComposerDraftModelReconciliation } from "./state/use-composer-drafts" ;
3950import { environmentThreadShells } from "./state/threads" ;
@@ -61,7 +72,12 @@ import {
6172} from "./features/workspace/workspace-selection-store" ;
6273import { workspaceDetailLinkAction } from "./features/workspace/workspace-detail-selection" ;
6374import { NativeLayoutMetricsProvider } from "./native/native-layout-metrics" ;
64- import { attachRootNavigation , rootNavigationRef } from "./lib/rootNavigation" ;
75+ import {
76+ attachRootNavigation ,
77+ flushRootNavigationQueue ,
78+ linkToRootPath ,
79+ rootNavigationRef ,
80+ } from "./lib/rootNavigation" ;
6581import { pruneNewTaskBranchCheckouts } from "./features/threads/NewTaskDraftRouteScreen" ;
6682
6783import "../global.css" ;
@@ -73,6 +89,20 @@ if (process.env.EXPO_PUBLIC_SHOWCASE === "1") {
7389void SplashScreen . preventAutoHideAsync ( ) . catch ( ( ) => { } ) ;
7490void hydrateWorkspaceSelections ( ) ;
7591
92+ const linkingConfig = {
93+ initialRouteName : "Home" ,
94+ screens : createPathConfigForStaticNavigation ( RootStack , { initialRouteName : "Home" } ) ?? { } ,
95+ } as const ;
96+
97+ function getAppStateFromPath ( path : string , options : Parameters < typeof getStateFromPath > [ 1 ] ) {
98+ return takeScheduledTaskNewLink (
99+ restoreSettingsLinkState (
100+ restoreDraftLinkState ( getStateFromPath ( path , options ) , path ) ,
101+ settingsLinkPage ( ) ,
102+ ) ,
103+ ) ;
104+ }
105+
76106const appLinking = {
77107 prefixes : [
78108 Linking . createURL ( "/" ) ,
@@ -91,25 +121,33 @@ const appLinking = {
91121 // Our router handles the selection; React Navigation's type only lists its own actions.
92122 ( workspaceDetailLinkAction ( state ) as ReturnType < typeof getActionFromState > ) ??
93123 getActionFromState ( state , options ) ,
94- getStateFromPath : ( path : string , options : Parameters < typeof getStateFromPath > [ 1 ] ) =>
95- takeScheduledTaskNewLink (
96- restoreSettingsLinkState (
97- restoreDraftLinkState ( getStateFromPath ( path , options ) , path ) ,
98- settingsLinkPage ( ) ,
99- ) ,
100- ) ,
124+ getStateFromPath : getAppStateFromPath ,
101125} ;
102126
127+ function appLinkAction ( href : string ) : NavigationAction {
128+ const state = getAppStateFromPath ( href , linkingConfig ) ;
129+ if ( ! state ) throw new Error ( `Failed to parse the href to a navigation state (${ href } ).` ) ;
130+ return appLinking . getActionFromState ( state , linkingConfig ) ?? CommonActions . reset ( state ) ;
131+ }
132+
133+ function linkToAppPath ( href : string ) : void {
134+ linkToRootPath ( href , appLinkAction ) ;
135+ }
136+
103137const Navigation = createStaticNavigation ( RootStack ) ;
104138
105139function handleNavigationStateChange ( state : NavigationState | undefined ) : void {
106140 recordWorkspaceSelections ( state ) ;
107- if ( state ) pruneNewTaskBranchCheckouts ( state ) ;
108141 presentPendingIncomingShare ( ) ;
142+ if ( ! state ) return ;
143+ setAgentNotificationPathname ( workspaceLocationFromState ( state ) . pathname ) ;
144+ recordAppShortcutNavigationState ( state ) ;
145+ pruneNewTaskBranchCheckouts ( state ) ;
109146}
110147
111148function handleNavigationReady ( ) : void {
112149 handleNavigationStateChange ( rootNavigationRef . getRootState ( ) ) ;
150+ flushRootNavigationQueue ( ) ;
113151}
114152
115153declare const module : { readonly hot ?: FoundationHotModule } | undefined ;
@@ -128,6 +166,8 @@ const appServiceDisposers = [
128166 installThreadOutboxDelivery ( ) ,
129167 installComposerAttachmentUploads ( ) ,
130168 startIncomingShareInbox ( ) ,
169+ installAgentNotificationNavigation ( linkToAppPath ) ,
170+ installAppShortcuts ( linkToAppPath ) ,
131171] ;
132172disposeOnFoundationReplace ( typeof module === "undefined" ? undefined : module . hot , ( ) => {
133173 for ( const dispose of appServiceDisposers ) dispose ( ) ;
0 commit comments