cortena-ui 1.4.2 → 1.6.0
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/CHANGELOG.md +107 -0
- package/LICENSE +7 -0
- package/README.md +235 -3
- package/dist/a2ui/views.js +2 -2
- package/dist/agent-chat/a2ui-block.d.ts +60 -0
- package/dist/agent-chat/a2ui-block.js +69 -0
- package/dist/agent-chat/a2ui-block.js.map +1 -0
- package/dist/agent-chat/agui-client.d.ts +40 -0
- package/dist/agent-chat/agui-client.js +251 -0
- package/dist/agent-chat/agui-client.js.map +1 -0
- package/dist/agent-chat/bridge.d.ts +109 -0
- package/dist/agent-chat/bridge.js +353 -0
- package/dist/agent-chat/bridge.js.map +1 -0
- package/dist/agent-chat/session.d.ts +79 -0
- package/dist/agent-chat/session.js +391 -0
- package/dist/agent-chat/session.js.map +1 -0
- package/dist/agent-chat/step-label.d.ts +99 -0
- package/dist/agent-chat/step-label.js +116 -0
- package/dist/agent-chat/step-label.js.map +1 -0
- package/dist/agent-chat/store.d.ts +102 -0
- package/dist/agent-chat/store.js +876 -0
- package/dist/agent-chat/store.js.map +1 -0
- package/dist/agent-chat/types.d.ts +277 -0
- package/dist/agent-chat/types.js +17 -0
- package/dist/agent-chat/types.js.map +1 -0
- package/dist/agent-chat.d.ts +11 -0
- package/dist/agent-chat.js +11 -0
- package/dist/components/admin-permissions/admin-permissions.d.ts +66 -0
- package/dist/components/admin-permissions/admin-permissions.js +101 -0
- package/dist/components/admin-permissions/admin-permissions.js.map +1 -0
- package/dist/components/admin-permissions/context.d.ts +70 -0
- package/dist/components/admin-permissions/context.js +258 -0
- package/dist/components/admin-permissions/context.js.map +1 -0
- package/dist/components/admin-permissions/index.d.ts +10 -0
- package/dist/components/admin-permissions/licence.d.ts +15 -0
- package/dist/components/admin-permissions/licence.js +78 -0
- package/dist/components/admin-permissions/licence.js.map +1 -0
- package/dist/components/admin-permissions/matrix.d.ts +20 -0
- package/dist/components/admin-permissions/matrix.js +191 -0
- package/dist/components/admin-permissions/matrix.js.map +1 -0
- package/dist/components/admin-permissions/members.d.ts +18 -0
- package/dist/components/admin-permissions/members.js +185 -0
- package/dist/components/admin-permissions/members.js.map +1 -0
- package/dist/components/admin-permissions/role-assignment.d.ts +35 -0
- package/dist/components/admin-permissions/role-assignment.js +174 -0
- package/dist/components/admin-permissions/role-assignment.js.map +1 -0
- package/dist/components/admin-permissions/roles.d.ts +25 -0
- package/dist/components/admin-permissions/roles.js +168 -0
- package/dist/components/admin-permissions/roles.js.map +1 -0
- package/dist/components/admin-permissions/types.d.ts +152 -0
- package/dist/components/admin-permissions/types.js +63 -0
- package/dist/components/admin-permissions/types.js.map +1 -0
- package/dist/components/agent-chat-popup.d.ts +29 -0
- package/dist/components/agent-chat-popup.js +188 -0
- package/dist/components/agent-chat-popup.js.map +1 -0
- package/dist/components/agent-chat.d.ts +163 -0
- package/dist/components/agent-chat.js +673 -0
- package/dist/components/agent-chat.js.map +1 -0
- package/dist/components/app-shell.d.ts +126 -0
- package/dist/components/app-shell.js +297 -0
- package/dist/components/app-shell.js.map +1 -0
- package/dist/components/badge.d.ts +1 -1
- package/dist/components/button-link.js +1 -1
- package/dist/components/button.d.ts +1 -1
- package/dist/components/checkbox.d.ts +1 -1
- package/dist/components/combobox.d.ts +1 -1
- package/dist/components/combobox.js +1 -1
- package/dist/components/consent-screen.d.ts +65 -0
- package/dist/components/consent-screen.js +123 -0
- package/dist/components/consent-screen.js.map +1 -0
- package/dist/components/data-table/data-table.d.ts +15 -1
- package/dist/components/data-table/data-table.js +18 -4
- package/dist/components/data-table/data-table.js.map +1 -1
- package/dist/components/data-table/index.d.ts +4 -4
- package/dist/components/data-table/parts.d.ts +27 -3
- package/dist/components/data-table/parts.js +175 -55
- package/dist/components/data-table/parts.js.map +1 -1
- package/dist/components/data-table/types.d.ts +61 -0
- package/dist/components/data-table/use-data-table.js +91 -6
- package/dist/components/data-table/use-data-table.js.map +1 -1
- package/dist/components/data-table/use-server-source.js +119 -28
- package/dist/components/data-table/use-server-source.js.map +1 -1
- package/dist/components/help-panel.d.ts +131 -0
- package/dist/components/help-panel.js +545 -0
- package/dist/components/help-panel.js.map +1 -0
- package/dist/components/login-screen.d.ts +127 -0
- package/dist/components/login-screen.js +339 -0
- package/dist/components/login-screen.js.map +1 -0
- package/dist/components/session-guard.d.ts +268 -0
- package/dist/components/session-guard.js +632 -0
- package/dist/components/session-guard.js.map +1 -0
- package/dist/components/toast.d.ts +1 -1
- package/dist/core.d.ts +5 -1
- package/dist/core.js +11 -7
- package/dist/data-table.d.ts +13 -4
- package/dist/data-table.js +10 -2
- package/dist/hooks/use-cortena-theme.js +49 -3
- package/dist/hooks/use-cortena-theme.js.map +1 -1
- package/dist/index.d.ts +17 -4
- package/dist/index.js +21 -8
- package/dist/markdown.d.ts +2 -1
- package/dist/markdown.js +2 -1
- package/package.json +18 -5
- package/src/agent-chat/a2ui-block.ts +118 -0
- package/src/agent-chat/agui-client.ts +405 -0
- package/src/agent-chat/bridge.ts +445 -0
- package/src/agent-chat/session.ts +549 -0
- package/src/agent-chat/step-label.ts +177 -0
- package/src/agent-chat/store.ts +1234 -0
- package/src/agent-chat/types.ts +308 -0
- package/src/components/admin-permissions/admin-permissions.tsx +130 -0
- package/src/components/admin-permissions/context.tsx +376 -0
- package/src/components/admin-permissions/index.tsx +32 -0
- package/src/components/admin-permissions/licence.tsx +84 -0
- package/src/components/admin-permissions/matrix.tsx +257 -0
- package/src/components/admin-permissions/members.tsx +204 -0
- package/src/components/admin-permissions/role-assignment.tsx +239 -0
- package/src/components/admin-permissions/roles.tsx +169 -0
- package/src/components/admin-permissions/types.ts +231 -0
- package/src/components/agent-chat-popup.tsx +289 -0
- package/src/components/agent-chat.tsx +1006 -0
- package/src/components/app-shell.tsx +502 -0
- package/src/components/consent-screen.tsx +239 -0
- package/src/components/data-table/data-table.tsx +36 -0
- package/src/components/data-table/index.tsx +6 -1
- package/src/components/data-table/parts.tsx +223 -47
- package/src/components/data-table/types.ts +68 -0
- package/src/components/data-table/use-data-table.ts +152 -4
- package/src/components/data-table/use-server-source.ts +150 -12
- package/src/components/help-panel.tsx +765 -0
- package/src/components/login-screen.tsx +479 -0
- package/src/components/session-guard.tsx +1071 -0
- package/src/entries/agent-chat.ts +137 -0
- package/src/entries/core.ts +8 -0
- package/src/entries/data-table.ts +41 -0
- package/src/entries/markdown.ts +25 -0
- package/src/hooks/use-cortena-theme.ts +63 -4
- package/src/index.ts +6 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { DialogContentProps } from "./dialog.js";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
//#region src/components/session-guard.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* SessionGuard — the shared session-expiry behaviour every Cortena surface
|
|
7
|
+
* wears (how-to-create-a-cortena-extension §9.4, audit rule P-37, decision
|
|
8
|
+
* DESIGN-D18).
|
|
9
|
+
*
|
|
10
|
+
* A user is warned before their session ends — Continue or Log out — and is
|
|
11
|
+
* logged out if they do nothing. Identical in every extension, in cortenaweb
|
|
12
|
+
* and in the agent pop-up, because an idle timeout that differs in length,
|
|
13
|
+
* warning or cross-tab behaviour between surfaces is one a user cannot learn.
|
|
14
|
+
*
|
|
15
|
+
* ## Two clocks, and two authorities
|
|
16
|
+
*
|
|
17
|
+
* There are two clocks and they are not the same clock:
|
|
18
|
+
*
|
|
19
|
+
* the access token plumbing. One hour, refreshed proactively at 75% of its
|
|
20
|
+
* life while the user is active. The user never sees it.
|
|
21
|
+
* Refreshing lazily on a 401 is the failure this component
|
|
22
|
+
* exists to remove: the first click after any pause fails,
|
|
23
|
+
* and if the refresh token has itself gone the screen is
|
|
24
|
+
* left half-dead — panels rendered from cache, every
|
|
25
|
+
* action silently doing nothing, no message anywhere.
|
|
26
|
+
* the idle timeout the user's. Reset by the user's hands, never by a
|
|
27
|
+
* background refresh, and always announced before it fires.
|
|
28
|
+
*
|
|
29
|
+
* And two authorities. **This guard is the experience; cortena-auth is the
|
|
30
|
+
* truth.** The countdown, the modal and the cross-tab handshake are here so the
|
|
31
|
+
* screen behaves; the decision that a session has actually ended is the refresh
|
|
32
|
+
* endpoint's, which refuses with `session_idle_expired` or `session_expired`.
|
|
33
|
+
* A browser clock can be wrong, paused by a sleeping laptop or moved by the
|
|
34
|
+
* user, so nothing here is a security boundary. A refresh that fails, for any
|
|
35
|
+
* reason and at any moment, is a signed-out state.
|
|
36
|
+
*
|
|
37
|
+
* ## The JWT claim contract it consumes
|
|
38
|
+
*
|
|
39
|
+
* The guard reads three claims out of the access token's payload, and it does
|
|
40
|
+
* so **by decoding, not by verifying**: it splits on `.`, base64url-decodes the
|
|
41
|
+
* middle segment and parses the JSON. No signature is checked, and none can be
|
|
42
|
+
* — the browser has no key, and it has no need of one, because nothing in this
|
|
43
|
+
* component is a decision the server will honour. A forged token buys an
|
|
44
|
+
* attacker a longer countdown on their own screen and nothing else; every
|
|
45
|
+
* request it is attached to is still verified by cortena-auth.
|
|
46
|
+
*
|
|
47
|
+
* `iat` epoch seconds. When the token was minted. The origin for the
|
|
48
|
+
* proactive refresh and for the absolute cap.
|
|
49
|
+
* `exp` epoch seconds. When it expires. Refresh fires at
|
|
50
|
+
* `iat + 0.75 * (exp - iat)`.
|
|
51
|
+
* `idle_exp` epoch seconds. When cortena-auth will call the session idle.
|
|
52
|
+
* Seeds the idle clock at mount, so a page reload after a long
|
|
53
|
+
* pause does not hand the user a fresh eight hours.
|
|
54
|
+
* `session_exp` epoch seconds. The absolute cap, equal to the refresh
|
|
55
|
+
* token's lifetime. It does not move, however active the user.
|
|
56
|
+
*
|
|
57
|
+
* Anything malformed, absent or unparseable falls back to the policy defaults
|
|
58
|
+
* (8 h idle, 12 h absolute, a 2 min warning) rather than throwing: a token this
|
|
59
|
+
* component cannot read must not be what stops a user working.
|
|
60
|
+
*
|
|
61
|
+
* An explicit `policy` value **replaces** the matching claim outright. That is
|
|
62
|
+
* the one rule; it is what makes the guide's twelve-second session and the
|
|
63
|
+
* tests' deterministic windows possible without a fabricated token.
|
|
64
|
+
*
|
|
65
|
+
* ## What resets what
|
|
66
|
+
*
|
|
67
|
+
* pointer, keyboard, `visibilitychange` reset the idle clock, while the
|
|
68
|
+
* state is `active`. Not network traffic — a polling screen left open on
|
|
69
|
+
* a desk is not a user. Not while the warning is up either: a modal that
|
|
70
|
+
* a stray mouse movement dismisses has not asked the user anything.
|
|
71
|
+
* Continue records activity and refreshes the token. The only thing that
|
|
72
|
+
* clears the warning.
|
|
73
|
+
* a refresh moves the access-token clock and nothing else. If a background
|
|
74
|
+
* refresh reset the idle clock, the idle timeout would never fire.
|
|
75
|
+
*
|
|
76
|
+
* Everything is shared across tabs over `BroadcastChannel`, so activity in one
|
|
77
|
+
* tab keeps them all alive and **one Continue answers every open tab**. Without
|
|
78
|
+
* it a user with three tabs open gets three modals and can dismiss the wrong
|
|
79
|
+
* one.
|
|
80
|
+
*
|
|
81
|
+
* ```tsx
|
|
82
|
+
* <SessionGuard
|
|
83
|
+
* token={{ accessToken }}
|
|
84
|
+
* refresh={() => auth.refresh()} // POST /api/auth/refresh
|
|
85
|
+
* logout={() => auth.logout()} // POST /api/auth/logout
|
|
86
|
+
* onSignedOut={(reason) => setSignedOut(reason)}
|
|
87
|
+
* />
|
|
88
|
+
* ```
|
|
89
|
+
*
|
|
90
|
+
* `onSignedOut` is where the app renders `LoginScreen` with `signedOut` and a
|
|
91
|
+
* `returnTo` (§7.4). Never a broken screen, never a spinner that never
|
|
92
|
+
* resolves — which is why the guard hands the reason back rather than
|
|
93
|
+
* redirecting itself.
|
|
94
|
+
*/
|
|
95
|
+
/** Why the session ended. Handed to `onSignedOut` so the app can word it. */
|
|
96
|
+
export type SessionSignOutReason = "idle" | "absolute" | "refresh_failed" | "user";
|
|
97
|
+
/** What the guard shows: counting quietly, counting out loud, or over. */
|
|
98
|
+
export type SessionState = "active" | "warning" | "signedOut";
|
|
99
|
+
export interface SessionToken {
|
|
100
|
+
/** The current access token. Decoded, never verified; see the note above. */
|
|
101
|
+
accessToken: string;
|
|
102
|
+
/**
|
|
103
|
+
* When it expires, for a token whose `exp` cannot be read — an opaque token,
|
|
104
|
+
* or one this guard failed to parse. Epoch **milliseconds**; a value below
|
|
105
|
+
* `1e11` is read as epoch seconds instead, since no millisecond timestamp has
|
|
106
|
+
* been that small since 1973 and every second-based one will be until 5138.
|
|
107
|
+
*/
|
|
108
|
+
expiresAt?: number;
|
|
109
|
+
}
|
|
110
|
+
export interface SessionPolicy {
|
|
111
|
+
/** How long an unattended screen stays signed in. Default 8 hours. */
|
|
112
|
+
idleMs: number;
|
|
113
|
+
/** The cap, however active the user has been. Default 12 hours. */
|
|
114
|
+
absoluteMs: number;
|
|
115
|
+
/** How long before the end the modal appears. Default 2 minutes. */
|
|
116
|
+
warnMs: number;
|
|
117
|
+
}
|
|
118
|
+
/** The org policy's defaults, used when neither `policy` nor a claim says otherwise. */
|
|
119
|
+
export declare const DEFAULT_SESSION_POLICY: SessionPolicy;
|
|
120
|
+
/**
|
|
121
|
+
* `setTimeout`/`clearTimeout`, injectable so a test can drive a whole session
|
|
122
|
+
* in a millisecond without the flake a real clock brings.
|
|
123
|
+
*/
|
|
124
|
+
export interface SessionTimers {
|
|
125
|
+
setTimeout: (handler: () => void, ms: number) => unknown;
|
|
126
|
+
clearTimeout: (handle: unknown) => void;
|
|
127
|
+
}
|
|
128
|
+
/** The default `BroadcastChannel` name. One channel per origin is the point. */
|
|
129
|
+
export declare const SESSION_CHANNEL_NAME = "cortena-session";
|
|
130
|
+
/** What tabs say to each other. Deliberately tiny: no token ever crosses it. */
|
|
131
|
+
export type SessionGuardMessage = {
|
|
132
|
+
type: "activity";
|
|
133
|
+
at: number;
|
|
134
|
+
} | {
|
|
135
|
+
type: "continue";
|
|
136
|
+
at: number;
|
|
137
|
+
} |
|
|
138
|
+
/**
|
|
139
|
+
* One tab rotated the credential. The token itself never crosses — only
|
|
140
|
+
* when the new one expires, which is all another tab needs to re-plan its
|
|
141
|
+
* own proactive refresh instead of racing to rotate again.
|
|
142
|
+
*/
|
|
143
|
+
{
|
|
144
|
+
type: "refreshed";
|
|
145
|
+
expiresAt?: number;
|
|
146
|
+
} |
|
|
147
|
+
/**
|
|
148
|
+
* The fallback claim, for a browser with no `navigator.locks`. `nonce` is
|
|
149
|
+
* the ballot: the highest one wins the election and rotates, and every other
|
|
150
|
+
* tab waits for that tab's `refreshed`. A claim without one comes from a tab
|
|
151
|
+
* running an older build and loses every election it takes part in, which
|
|
152
|
+
* still leaves exactly one refresher.
|
|
153
|
+
*/
|
|
154
|
+
{
|
|
155
|
+
type: "refresh-claim";
|
|
156
|
+
at: number;
|
|
157
|
+
nonce?: string;
|
|
158
|
+
} | {
|
|
159
|
+
type: "signed-out";
|
|
160
|
+
reason: SessionSignOutReason;
|
|
161
|
+
};
|
|
162
|
+
export interface SessionClaims {
|
|
163
|
+
/** `iat`, in epoch milliseconds. */
|
|
164
|
+
issuedAt?: number;
|
|
165
|
+
/** `exp`, in epoch milliseconds. */
|
|
166
|
+
expiresAt?: number;
|
|
167
|
+
/** `idle_exp`, in epoch milliseconds. */
|
|
168
|
+
idleExpiresAt?: number;
|
|
169
|
+
/** `session_exp`, in epoch milliseconds. */
|
|
170
|
+
sessionExpiresAt?: number;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* The four session claims out of a JWT payload, **decoded and not verified**.
|
|
174
|
+
*
|
|
175
|
+
* Returns `{}` for anything that is not a readable JWT — an opaque token, a
|
|
176
|
+
* truncated one, a payload that is not JSON. It never throws: a token the guard
|
|
177
|
+
* cannot read falls back to the policy defaults, because a parse error must not
|
|
178
|
+
* be what ends a user's session.
|
|
179
|
+
*/
|
|
180
|
+
export declare function decodeSessionClaims(accessToken: string | undefined): SessionClaims;
|
|
181
|
+
export interface UseSessionGuardOptions {
|
|
182
|
+
token: SessionToken;
|
|
183
|
+
/** `POST /api/auth/refresh`. Resolves with the rotated access token. */
|
|
184
|
+
refresh: () => Promise<{
|
|
185
|
+
accessToken: string;
|
|
186
|
+
}>;
|
|
187
|
+
/** `POST /api/auth/logout`. Revokes the refresh token and clears storage. */
|
|
188
|
+
logout: () => Promise<void>;
|
|
189
|
+
/**
|
|
190
|
+
* The session is over. Render `LoginScreen` with `signedOut` and a
|
|
191
|
+
* `returnTo`; the guard does not navigate.
|
|
192
|
+
*/
|
|
193
|
+
onSignedOut: (reason: SessionSignOutReason) => void;
|
|
194
|
+
/** Org policy from `GET /api/orgs/:orgId/session-policy`. Replaces the claims. */
|
|
195
|
+
policy?: Partial<SessionPolicy>;
|
|
196
|
+
/** The `BroadcastChannel` name. One per origin unless two apps must not share. */
|
|
197
|
+
channelName?: string;
|
|
198
|
+
/** The clock. Injected by tests and by the guide; `Date.now` otherwise. */
|
|
199
|
+
now?: () => number;
|
|
200
|
+
/** The timers. Injected by tests and by the guide; `setTimeout` otherwise. */
|
|
201
|
+
timers?: SessionTimers;
|
|
202
|
+
}
|
|
203
|
+
export interface UseSessionGuardResult {
|
|
204
|
+
/** `active` while it counts quietly, `warning` while the modal is up. */
|
|
205
|
+
state: SessionState;
|
|
206
|
+
/** Milliseconds left until the session ends. `0` once it has. */
|
|
207
|
+
remainingMs: number;
|
|
208
|
+
/**
|
|
209
|
+
* Whether Continue can buy the user anything. False once the absolute cap is
|
|
210
|
+
* the binding deadline, because no amount of activity moves that one.
|
|
211
|
+
*/
|
|
212
|
+
canContinue: boolean;
|
|
213
|
+
/** Set once the session has ended. */
|
|
214
|
+
reason?: SessionSignOutReason;
|
|
215
|
+
/** The idle deadline, epoch ms. Moves with the user's hands. */
|
|
216
|
+
idleDeadline: number;
|
|
217
|
+
/** The absolute cap, epoch ms. Does not move. */
|
|
218
|
+
absoluteDeadline: number;
|
|
219
|
+
/** Whichever of the two comes first. */
|
|
220
|
+
deadline: number;
|
|
221
|
+
/** Record activity and refresh the token. What Continue calls. */
|
|
222
|
+
continueSession: () => void;
|
|
223
|
+
/** End the session now. What Log out calls, with `"user"`. */
|
|
224
|
+
signOut: (reason?: SessionSignOutReason) => void;
|
|
225
|
+
/** Record activity by hand, for an app with an activity signal of its own. */
|
|
226
|
+
recordActivity: () => void;
|
|
227
|
+
}
|
|
228
|
+
export declare function useSessionGuard(options: UseSessionGuardOptions): UseSessionGuardResult;
|
|
229
|
+
/** `m:ss`, rounded up, so the countdown reaches 0:00 exactly as it ends. */
|
|
230
|
+
export declare function formatCountdown(ms: number): string;
|
|
231
|
+
export interface SessionExpiryDialogProps {
|
|
232
|
+
open: boolean;
|
|
233
|
+
/** Milliseconds left. Rendered as `m:ss`. */
|
|
234
|
+
remainingMs: number;
|
|
235
|
+
/** Whether Continue is offered. False under the absolute cap, which no activity moves. */
|
|
236
|
+
canContinue?: boolean;
|
|
237
|
+
onContinue?: () => void;
|
|
238
|
+
onLogout?: () => void;
|
|
239
|
+
/** Non-modal for the guide, where three theme frames must not fight over focus. */
|
|
240
|
+
modal?: boolean;
|
|
241
|
+
/** Where to portal. The guide frames it; the product does not pass this. */
|
|
242
|
+
container?: DialogContentProps["container"];
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* The countdown. `role="alertdialog"` rather than `dialog`, because it is not a
|
|
246
|
+
* surface the user opened — it interrupts them to ask a question with a
|
|
247
|
+
* deadline, and assistive technology announces it as such.
|
|
248
|
+
*
|
|
249
|
+
* It is deliberately undismissable: no Escape, no outside press, no close X.
|
|
250
|
+
* Both ways out are decisions — Continue or Log out — and a modal you can wave
|
|
251
|
+
* away without answering is one that ends a session by accident. Focus opens on
|
|
252
|
+
* Continue, which is the answer nearly every user wants.
|
|
253
|
+
*/
|
|
254
|
+
export declare function SessionExpiryDialog({ open, remainingMs, canContinue, onContinue, onLogout, modal, container }: SessionExpiryDialogProps): React.JSX.Element;
|
|
255
|
+
export interface SessionGuardProps extends UseSessionGuardOptions {
|
|
256
|
+
/** Non-modal, for the guide. The product leaves this alone. */
|
|
257
|
+
modal?: boolean;
|
|
258
|
+
/** Where to portal the modal — an agent pop-up's own root, say. */
|
|
259
|
+
container?: DialogContentProps["container"];
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Mount one per surface: the shell mounts it, and so does the agent pop-up
|
|
263
|
+
* (§17). A user whose extension warns them while the chat pop-up beside it does
|
|
264
|
+
* not has learned nothing about how long a Cortena session lasts.
|
|
265
|
+
*/
|
|
266
|
+
export declare function SessionGuard({ modal, container, ...options }: SessionGuardProps): React.JSX.Element;
|
|
267
|
+
//#endregion
|
|
268
|
+
//# sourceMappingURL=session-guard.d.ts.map
|