@kortix/ui 0.14.5 → 0.14.6
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/access/access/access-dialog.js +8 -5
- package/dist/access/access/copy-row.js +2 -2
- package/dist/access/sharing-picker.js +2 -1
- package/dist/browser/app-in-browser.js +5 -3
- package/dist/browser/browser-panel.js +6 -6
- package/dist/browser/sandbox-browser-chrome.d.ts +4 -1
- package/dist/browser/sandbox-browser-chrome.js +4 -3
- package/dist/customize/agents/agent-access.d.ts +20 -0
- package/dist/customize/agents/agent-access.js +17 -0
- package/dist/customize/agents/agent-grant-pages.js +5 -6
- package/dist/customize/agents/agent-page.js +2 -1
- package/dist/customize/agents/agents-page.js +18 -1
- package/dist/customize/connectors/add-mcp/add-mcp-server.js +4 -2
- package/dist/customize/connectors/connector-routes.d.ts +3 -1
- package/dist/customize/connectors/connector-routes.js +18 -0
- package/dist/customize/connectors/connectors-page.js +23 -4
- package/dist/customize/connectors/detail/connector-advanced-tools.js +4 -6
- package/dist/customize/providers/provider-accordion.js +2 -1
- package/dist/customize/providers/provider-connect.js +2 -1
- package/dist/customize/sections/component/telegram-channel-row.js +1 -1
- package/dist/customize/sections/connector-connection-modal.js +11 -9
- package/dist/customize/sections/connectors-view.js +11 -13
- package/dist/customize/sections/view/gateway/gateway-routing.js +15 -18
- package/dist/customize/settings/rail-copy-context.js +5 -3
- package/dist/customize/settings/tabs/sandbox-template-form.js +9 -12
- package/dist/customize/shared/capability-tabs.js +2 -1
- package/dist/customize/skills/skills-page.js +3 -5
- package/dist/customize/triggers/schedule/event-trigger-copy.js +3 -2
- package/dist/customize/triggers/schedule/schedule-builder.js +7 -4
- package/dist/customize/triggers/schedule/trigger-composer.js +5 -2
- package/dist/customize/triggers/schedule/when-event.js +1 -1
- package/dist/diff/diff-view.js +9 -10
- package/dist/files/editor/code-editor.js +2 -3
- package/dist/files/project/components/change-request-detail-dialog.d.ts +3 -1
- package/dist/files/project/components/change-request-detail-dialog.js +3 -5
- package/dist/files/project/components/change-request-status-badge.d.ts +12 -0
- package/dist/files/project/components/change-request-status-badge.js +27 -0
- package/dist/files/project/components/change-requests-panel.js +1 -1
- package/dist/files/project/components/drive-explorer.js +2 -1
- package/dist/files/project/components/drive-grid-view.js +11 -7
- package/dist/files/project/components/drive-list-view.js +4 -4
- package/dist/files/project/components/file-breadcrumbs.js +1 -1
- package/dist/files/project/components/file-explorer-page.js +1 -1
- package/dist/files/project/components/file-history-popover.js +1 -6
- package/dist/files/project/components/file-search.js +6 -1
- package/dist/files/project/components/open-change-request-dialog.js +2 -1
- package/dist/files/project/components/version-selector-logic.d.ts +11 -0
- package/dist/files/project/components/version-selector-logic.js +26 -0
- package/dist/files/project/components/version-selector.js +11 -20
- package/dist/files/project/hooks/use-server-health.js +17 -15
- package/dist/files/renderers/docx/docx-viewer.js +0 -5
- package/dist/files/renderers/image-renderer.js +6 -24
- package/dist/files/renderers/pdf/pdf-viewer.js +1 -1
- package/dist/files/renderers/presentation/FullScreenPresentationViewer.js +2 -11
- package/dist/files/renderers/show-content-renderer.js +1 -1
- package/dist/files/renderers/sqlite-renderer.js +8 -3
- package/dist/files/renderers/xlsx/xlsx-viewer.js +15 -16
- package/dist/files/tree/components/file-tree-item.js +1 -1
- package/dist/files/viewer/file-preview-modal.js +1 -1
- package/dist/files/viewer/use-file-content-state.js +1 -1
- package/dist/i18n/en.d.ts +10 -0
- package/dist/i18n/en.js +10 -0
- package/dist/internal/desktop/desktop-back-button.js +5 -3
- package/dist/internal/hooks/use-auto-scroll.js +5 -3
- package/dist/internal/notifications/notification-rows.js +2 -1
- package/dist/internal/outcomes/outcome-types.d.ts +5 -0
- package/dist/markdown/code/inline-code.js +8 -0
- package/dist/markdown/code/output-paths-context.d.ts +18 -0
- package/dist/markdown/code/output-paths-context.js +35 -0
- package/dist/markdown/genui/components/charts.js +6 -5
- package/dist/primitives/map.js +2 -1
- package/dist/primitives/preview-image.js +4 -2
- package/dist/primitives/textarea.js +1 -1
- package/dist/primitives/typed-title.js +12 -14
- package/dist/primitives/typing-animation.js +4 -2
- package/dist/session/composer/agent-selector.js +6 -1
- package/dist/session/composer/composer-chat-input.js +5 -3
- package/dist/session/composer/composer-logic.js +8 -7
- package/dist/session/composer/draft/composer-draft.js +4 -4
- package/dist/session/composer/pasted-text.js +3 -2
- package/dist/session/composer/stores/queued-draft-store.js +3 -2
- package/dist/session/header/reminder-parts.d.ts +11 -2
- package/dist/session/header/reminder-parts.js +9 -4
- package/dist/session/media/sandbox-url-detector.js +0 -7
- package/dist/session/outcomes/change-request-outcomes.js +24 -3
- package/dist/session/overrides/provider-secret-pool-editor.js +2 -1
- package/dist/session/panel/advanced/advanced-panel.js +3 -7
- package/dist/session/panel/easy/app-preview.js +12 -2
- package/dist/session/panel/easy/easy-panel-logic.d.ts +1 -1
- package/dist/session/panel/easy/easy-panel-logic.js +1 -1
- package/dist/session/panel/easy/outputs-card.js +2 -1
- package/dist/session/panel/easy/panel-card.js +5 -3
- package/dist/session/panel/easy/preview-load.d.ts +14 -0
- package/dist/session/panel/easy/preview-load.js +15 -0
- package/dist/session/panel/easy/step-detail-body.js +2 -7
- package/dist/session/panel/session-panel-provider.js +6 -2
- package/dist/session/panel/shared/use-panel-derivations.js +6 -4
- package/dist/session/panel/use-session-panel-layout.js +7 -5
- package/dist/session/print/session-print-header.js +9 -8
- package/dist/session/thread/session-chat.js +12 -9
- package/dist/session/thread/session-history.js +3 -1
- package/dist/session/thread/transcript.js +13 -7
- package/dist/session/tool/shared/file-list.js +19 -2
- package/dist/session/tool/shared/infrastructure-contexts.d.ts +7 -0
- package/dist/session/tool/shared/infrastructure-contexts.js +7 -0
- package/dist/session/tool/shared/infrastructure-output.js +9 -5
- package/dist/session/tool/shared/infrastructure-row-header.js +9 -1
- package/dist/session/tool/shared/infrastructure-rows.js +7 -5
- package/dist/session/tool/tools/bash-tool.js +10 -6
- package/dist/session/tool/tools/web-search-tool.js +25 -3
- package/dist/session/turn/recovered-failures.d.ts +8 -0
- package/dist/session/turn/recovered-failures.js +32 -0
- package/dist/session/turn/streaming-cadence.js +5 -8
- package/dist/styles.css +1 -1
- package/dist/terminal/session-terminal-panel.js +3 -5
- package/dist/theme/theme.js +2 -1
- package/dist/workspace/projects/modal/github-import-pickers.js +7 -6
- package/dist/workspace/review/review-center.js +13 -10
- package/dist/workspace/session-workspace.js +5 -9
- package/dist/workspace/sessions/deleted-session-row.js +5 -2
- package/dist/workspace/sidebar/footer/project-computer-nav.js +6 -4
- package/dist/workspace/sidebar/footer/project-mcp-nav.js +6 -2
- package/dist/workspace/sidebar/modal/rename-session-modal.js +8 -3
- package/package.json +3 -3
package/dist/i18n/en.d.ts
CHANGED
|
@@ -4068,6 +4068,8 @@ declare const catalog: {
|
|
|
4068
4068
|
texta4cf35d7f3ca: string;
|
|
4069
4069
|
texta4f264c3ab5f: string;
|
|
4070
4070
|
texta4fc39798651: string;
|
|
4071
|
+
textddcd87c21894: string;
|
|
4072
|
+
texta8ef31fa7d25: string;
|
|
4071
4073
|
texta514a684676a: string;
|
|
4072
4074
|
texta52ace420f21: string;
|
|
4073
4075
|
texta54220c82b33: string;
|
|
@@ -4286,6 +4288,11 @@ declare const catalog: {
|
|
|
4286
4288
|
textb6b7a0065808: string;
|
|
4287
4289
|
textb6bb289a7a2c: string;
|
|
4288
4290
|
textb6c70926c1aa: string;
|
|
4291
|
+
textf19611c61ca5: string;
|
|
4292
|
+
text15589a542412: string;
|
|
4293
|
+
texte96d99ad9896: string;
|
|
4294
|
+
text70b8d7e10749: string;
|
|
4295
|
+
text2d3f4433505a: string;
|
|
4289
4296
|
textb6cde9030cef: string;
|
|
4290
4297
|
textb6d85433a7ee: string;
|
|
4291
4298
|
textb70354a1faae: string;
|
|
@@ -4375,6 +4382,7 @@ declare const catalog: {
|
|
|
4375
4382
|
textbdb86505f806: string;
|
|
4376
4383
|
textbdbd7706de64: string;
|
|
4377
4384
|
textbdc0857b99a9: string;
|
|
4385
|
+
textbdc090ec61e3: string;
|
|
4378
4386
|
textbdc7d54433e6: string;
|
|
4379
4387
|
textbde05a7b8929: string;
|
|
4380
4388
|
textbe379a30f1aa: string;
|
|
@@ -6265,6 +6273,8 @@ declare const catalog: {
|
|
|
6265
6273
|
timeZone: string;
|
|
6266
6274
|
lastRun: string;
|
|
6267
6275
|
lastRunFailed: string;
|
|
6276
|
+
runQueued: string;
|
|
6277
|
+
runFailed: string;
|
|
6268
6278
|
neverRun: string;
|
|
6269
6279
|
searchPlaceholder: string;
|
|
6270
6280
|
statusAll: string;
|
package/dist/i18n/en.js
CHANGED
|
@@ -4069,6 +4069,8 @@ const catalog = {
|
|
|
4069
4069
|
"texta4cf35d7f3ca": "Provision a few sandboxes — their timing and outcome show up here.",
|
|
4070
4070
|
"texta4f264c3ab5f": "Admin Grant",
|
|
4071
4071
|
"texta4fc39798651": "Change request #{number}",
|
|
4072
|
+
"textddcd87c21894": "Superseded by #{number}",
|
|
4073
|
+
"texta8ef31fa7d25": "View #{number}",
|
|
4072
4074
|
"texta514a684676a": "Edit access",
|
|
4073
4075
|
"texta52ace420f21": "All",
|
|
4074
4076
|
"texta54220c82b33": "Optional at session start. Click to require this connector.",
|
|
@@ -4287,6 +4289,11 @@ const catalog = {
|
|
|
4287
4289
|
"textb6b7a0065808": "Repeat",
|
|
4288
4290
|
"textb6bb289a7a2c": "accounts teams organizations switch manage",
|
|
4289
4291
|
"textb6c70926c1aa": "Admins only",
|
|
4292
|
+
"textf19611c61ca5": "Full access",
|
|
4293
|
+
"text15589a542412": "{count, plural, =0 {No connectors} one {# connector} other {# connectors}}",
|
|
4294
|
+
"texte96d99ad9896": "{count, plural, =0 {No secrets} one {# secret} other {# secrets}}",
|
|
4295
|
+
"text70b8d7e10749": "All Kortix actions",
|
|
4296
|
+
"text2d3f4433505a": "{count, plural, =0 {No Kortix actions} one {# Kortix action} other {# Kortix actions}}",
|
|
4290
4297
|
"textb6cde9030cef": "Create key",
|
|
4291
4298
|
"textb6d85433a7ee": "Sessions could not be loaded",
|
|
4292
4299
|
"textb70354a1faae": "Foo 7B",
|
|
@@ -4376,6 +4383,7 @@ const catalog = {
|
|
|
4376
4383
|
"textbdb86505f806": "Archived",
|
|
4377
4384
|
"textbdbd7706de64": "How this works",
|
|
4378
4385
|
"textbdc0857b99a9": "Only me",
|
|
4386
|
+
"textbdc090ec61e3": "Reload",
|
|
4379
4387
|
"textbdc7d54433e6": "Failed to add connector",
|
|
4380
4388
|
"textbde05a7b8929": "Checking session",
|
|
4381
4389
|
"textbe379a30f1aa": "credits",
|
|
@@ -6266,6 +6274,8 @@ const catalog = {
|
|
|
6266
6274
|
"timeZone": "Time zone",
|
|
6267
6275
|
"lastRun": "Last run",
|
|
6268
6276
|
"lastRunFailed": "Last run failed",
|
|
6277
|
+
"runQueued": "Reminder sent to the session",
|
|
6278
|
+
"runFailed": "Could not run the reminder",
|
|
6269
6279
|
"neverRun": "Not run yet",
|
|
6270
6280
|
"searchPlaceholder": "Search reminders",
|
|
6271
6281
|
"statusAll": "All",
|
|
@@ -87,6 +87,8 @@ export function useDesktopBackTarget(href) {
|
|
|
87
87
|
};
|
|
88
88
|
}, [href]);
|
|
89
89
|
}
|
|
90
|
+
const subscribeNoop = () => () => { };
|
|
91
|
+
const readCanGoBack = () => Boolean(window.navigation?.canGoBack);
|
|
90
92
|
/** Pathname of an app href, for comparing against `useUiPathname()`. */
|
|
91
93
|
function hrefPath(href) {
|
|
92
94
|
return href.split(/[?#]/)[0] || '/';
|
|
@@ -119,10 +121,10 @@ export function DesktopBackButton() {
|
|
|
119
121
|
const pathname = useUiPathname() ?? '/';
|
|
120
122
|
const home = useAppHome();
|
|
121
123
|
const to = useSyncExternalStore(subscribeBackTarget, () => backTarget, () => undefined);
|
|
124
|
+
const canGoBack = useSyncExternalStore(subscribeNoop, readCanGoBack, () => false);
|
|
122
125
|
if (!viewerId)
|
|
123
126
|
return null;
|
|
124
|
-
|
|
125
|
-
if (!hasBackDestination(win, { to, home, pathname }))
|
|
127
|
+
if (!hasBackDestination({ navigation: { canGoBack } }, { to, home, pathname }))
|
|
126
128
|
return null;
|
|
127
|
-
return _jsx(DesktopBackControl, { onBack: () => void goBack(router,
|
|
129
|
+
return _jsx(DesktopBackControl, { onBack: () => void goBack(router, window, { to, home }) });
|
|
128
130
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
3
3
|
import { OWN_SCROLL_MS, chevronVisible, isAtEnd, keyScrollIntentFor, pickAnchorIndex, prefersReducedMotion, roomUnderNewestTurn, settleMotion, shouldReleaseFollow, } from './use-auto-scroll-physics.js';
|
|
4
4
|
export { AT_END_PX, BOTTOM_GAP_PX, CHEVRON_PX, GLIDE_MIN_PX, OWN_SCROLL_MS, TURN_TOP_OFFSET, chevronVisible, classifyScrollKey, isAtEnd, isEditableTarget, isSpaceActivatedTarget, keyScrollIntentFor, pickAnchorIndex, roomUnderNewestTurn, settleMotion, shouldReleaseFollow, } from './use-auto-scroll-physics.js';
|
|
5
5
|
/**
|
|
@@ -234,7 +234,9 @@ export function useAutoScroll({ hasContent = false, } = {}) {
|
|
|
234
234
|
markOwnScroll(OWN_SCROLL_MS);
|
|
235
235
|
el.scrollTop = end;
|
|
236
236
|
}, [sizeRoom, glideTo, markOwnScroll]);
|
|
237
|
-
|
|
237
|
+
useLayoutEffect(() => {
|
|
238
|
+
settleRef.current = settle;
|
|
239
|
+
}, [settle]);
|
|
238
240
|
const goToEnd = useCallback((behavior) => {
|
|
239
241
|
const el = scrollRef.current;
|
|
240
242
|
if (!el)
|
|
@@ -455,7 +457,7 @@ export function useAutoScroll({ hasContent = false, } = {}) {
|
|
|
455
457
|
document.removeEventListener('keydown', onKeyDown, { capture: true });
|
|
456
458
|
el.removeEventListener('scroll', onScroll);
|
|
457
459
|
};
|
|
458
|
-
}, [goToEnd, endGlide, hasContent, setFollow
|
|
460
|
+
}, [goToEnd, endGlide, hasContent, setFollow]);
|
|
459
461
|
return {
|
|
460
462
|
scrollRef,
|
|
461
463
|
contentRef,
|
|
@@ -44,10 +44,11 @@ export function newArrivals(seen, rows) {
|
|
|
44
44
|
* is not.
|
|
45
45
|
*/
|
|
46
46
|
export function planArrivals(fresh, context) {
|
|
47
|
+
const unseen = new Set(context.unseen);
|
|
47
48
|
const announce = fresh
|
|
48
49
|
.filter((row) => !row.session_id ||
|
|
49
50
|
(!context.onScreen(row.session_id) &&
|
|
50
|
-
!(row.kind === 'turn_done' &&
|
|
51
|
+
!(row.kind === 'turn_done' && unseen.has(row.session_id))))
|
|
51
52
|
.slice(0, MAX_ARRIVAL_ALERTS);
|
|
52
53
|
return context.os ? { toast: [], os: announce } : { toast: announce, os: [] };
|
|
53
54
|
}
|
|
@@ -49,6 +49,11 @@ export interface OutcomeAction {
|
|
|
49
49
|
intent: 'open' | 'link';
|
|
50
50
|
/** Required when `intent` is `link`; ignored otherwise. */
|
|
51
51
|
href?: string;
|
|
52
|
+
/**
|
|
53
|
+
* For `open`: the source id the modal opens when it is not this outcome's
|
|
54
|
+
* own. A superseded change request opens its replacement (KRTX-3031).
|
|
55
|
+
*/
|
|
56
|
+
target?: string;
|
|
52
57
|
}
|
|
53
58
|
export interface Outcome {
|
|
54
59
|
/**
|
|
@@ -12,6 +12,7 @@ import { useSessionBrowserStore } from '../../internal/stores/session-browser-st
|
|
|
12
12
|
import { useUiLink } from '../../providers/ui-provider.js';
|
|
13
13
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
14
14
|
import { useInsideLink } from './inside-link-context.js';
|
|
15
|
+
import { outputPathForName, useOutputPaths } from './output-paths-context.js';
|
|
15
16
|
import { childrenToText } from './children-text.js';
|
|
16
17
|
// Server-safe by design — see `inline-chip.tsx`. Re-exported so the client
|
|
17
18
|
// consumers that already import them from here keep working.
|
|
@@ -114,6 +115,7 @@ export function ClickableInlineCode({ children }) {
|
|
|
114
115
|
const { proxyUrl } = useSandboxProxy();
|
|
115
116
|
const openPreview = useOpenPreviewLink();
|
|
116
117
|
const insideLink = useInsideLink();
|
|
118
|
+
const outputPaths = useOutputPaths();
|
|
117
119
|
const text = childrenToText(children).trim();
|
|
118
120
|
// Before the URL and path checks: a hex is neither, and the test is a single
|
|
119
121
|
// anchored regex against a string that is at most nine characters.
|
|
@@ -146,5 +148,11 @@ export function ClickableInlineCode({ children }) {
|
|
|
146
148
|
if (looksLikeFilePath(text)) {
|
|
147
149
|
return _jsx(FilePathCode, { text: text, children: children });
|
|
148
150
|
}
|
|
151
|
+
// A bare filename (`claims.md`) is no path, but it may name one of this
|
|
152
|
+
// session's outputs: open that file, still showing the name.
|
|
153
|
+
const outputPath = outputPathForName(text, outputPaths);
|
|
154
|
+
if (outputPath) {
|
|
155
|
+
return _jsx(FilePathCode, { text: outputPath, children: children });
|
|
156
|
+
}
|
|
149
157
|
return _jsx("code", { className: INLINE_CODE, children: children });
|
|
150
158
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The paths of the files this session produced: its Outputs.
|
|
3
|
+
*
|
|
4
|
+
* A reply names its deliverables by bare filename (`claims.md`), and a bare
|
|
5
|
+
* name is not a path, so it never linked. Opening it took Expand pane →
|
|
6
|
+
* Outputs → the file (KRTX-3023). Inline code that names exactly one of these
|
|
7
|
+
* outputs now opens it.
|
|
8
|
+
*
|
|
9
|
+
* Provider: `SessionPanelProvider`. Empty outside a session: nothing extra links.
|
|
10
|
+
*/
|
|
11
|
+
export declare const OutputPathsContext: import("react").Context<readonly string[]>;
|
|
12
|
+
export declare const useOutputPaths: () => readonly string[];
|
|
13
|
+
/**
|
|
14
|
+
* The output a bare filename names, or null: it is not a filename, no output
|
|
15
|
+
* has that name, or two different outputs share it and the reply does not say
|
|
16
|
+
* which.
|
|
17
|
+
*/
|
|
18
|
+
export declare function outputPathForName(text: string, paths: readonly string[]): string | null;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { createContext, useContext } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* The paths of the files this session produced: its Outputs.
|
|
5
|
+
*
|
|
6
|
+
* A reply names its deliverables by bare filename (`claims.md`), and a bare
|
|
7
|
+
* name is not a path, so it never linked. Opening it took Expand pane →
|
|
8
|
+
* Outputs → the file (KRTX-3023). Inline code that names exactly one of these
|
|
9
|
+
* outputs now opens it.
|
|
10
|
+
*
|
|
11
|
+
* Provider: `SessionPanelProvider`. Empty outside a session: nothing extra links.
|
|
12
|
+
*/
|
|
13
|
+
export const OutputPathsContext = createContext([]);
|
|
14
|
+
export const useOutputPaths = () => useContext(OutputPathsContext);
|
|
15
|
+
const BARE_FILENAME = /^[\w@][\w@.-]*\.[A-Za-z0-9]+$/;
|
|
16
|
+
/** `/workspace/a/b.md` and `a/b.md` are one file. */
|
|
17
|
+
const sameFileKey = (path) => path.replace(/^\/workspace\//, '');
|
|
18
|
+
/**
|
|
19
|
+
* The output a bare filename names, or null: it is not a filename, no output
|
|
20
|
+
* has that name, or two different outputs share it and the reply does not say
|
|
21
|
+
* which.
|
|
22
|
+
*/
|
|
23
|
+
export function outputPathForName(text, paths) {
|
|
24
|
+
if (!BARE_FILENAME.test(text))
|
|
25
|
+
return null;
|
|
26
|
+
let found = null;
|
|
27
|
+
for (const path of paths) {
|
|
28
|
+
if (path.slice(path.lastIndexOf('/') + 1) !== text)
|
|
29
|
+
continue;
|
|
30
|
+
if (found !== null && sameFileKey(found) !== sameFileKey(path))
|
|
31
|
+
return null;
|
|
32
|
+
found ??= path;
|
|
33
|
+
}
|
|
34
|
+
return found;
|
|
35
|
+
}
|
|
@@ -25,7 +25,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
25
25
|
*/
|
|
26
26
|
// eslint-disable-next-line no-restricted-imports -- screen-reader text for the figure; this module is reached only through lazy()
|
|
27
27
|
import { genuiA11yText } from '@kortix/sdk/genui';
|
|
28
|
-
import { useState } from 'react';
|
|
28
|
+
import { useMemo, useState } from 'react';
|
|
29
29
|
import { Bar, BarChart, CartesianGrid, Cell, Line, LineChart, Pie, PieChart, XAxis, YAxis } from 'recharts';
|
|
30
30
|
import { ChartContainer, ChartTooltip, ChartTooltipContent } from '../../../primitives/chart.js';
|
|
31
31
|
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '../../../primitives/dialog.js';
|
|
@@ -95,7 +95,7 @@ function PieFigure({ variant, slices, total, unit, format, tooltip, focus, }) {
|
|
|
95
95
|
const restTotal = rest.reduce((sum, slice) => sum + slice.value, 0);
|
|
96
96
|
const block = (slice, i) => {
|
|
97
97
|
const small = i > 0 && slice.value / restTotal < 0.12;
|
|
98
|
-
return (_jsxs(HoverCard, { openDelay: 80, closeDelay: 40, children: [_jsx(HoverCardTrigger, { asChild: true, children: _jsx("
|
|
98
|
+
return (_jsxs(HoverCard, { openDelay: 80, closeDelay: 40, children: [_jsx(HoverCardTrigger, { asChild: true, children: _jsx("button", { type: "button", onMouseEnter: () => focus.hover(slice.key), onMouseLeave: () => focus.hover(null), onClick: () => focus.toggle(slice.key), "aria-label": `${slice.label}: ${format(slice.value)} (${slice.percent}%)`, className: cn('focus-visible:ring-ring duration-fast flex min-h-1.5 min-w-0 flex-col justify-between overflow-hidden rounded-md text-left transition-opacity outline-none focus-visible:ring-2', small ? 'p-0' : 'p-3', i < 2 ? 'text-background' : 'text-foreground'), style: { backgroundColor: PIE_RAMP[i], flexGrow: slice.value, flexBasis: 0, opacity: dimmed(focus, slice.key) }, children: small ? null : (_jsxs(_Fragment, { children: [_jsx("span", { className: "truncate text-xs", children: slice.label }), _jsxs("span", { className: cn('truncate tabular-nums', i === 0 ? 'text-2xl font-medium' : 'text-sm'), children: [slice.percent, "%"] })] })) }) }), _jsxs(HoverCardContent, { side: "top", className: "flex w-auto min-w-40 flex-col gap-1 p-3", children: [_jsxs("span", { className: "text-foreground flex items-center gap-2 text-sm font-medium", children: [dot(slice.fill), slice.label] }), _jsxs("span", { className: "text-muted-foreground font-mono text-xs tabular-nums", children: [unit ? `${format(slice.value)} ${unit}` : format(slice.value), " \u00B7 ", slice.percent, "%"] })] })] }, slice.key));
|
|
99
99
|
};
|
|
100
100
|
return (_jsxs("div", { className: "flex min-h-0 flex-1 gap-1", children: [block(first, 0), rest.length > 0 ? (_jsx("div", { className: "flex min-w-0 flex-col gap-1", style: { flexGrow: restTotal, flexBasis: 0 }, children: rest.map((slice, i) => block(slice, i + 1)) })) : null] }));
|
|
101
101
|
}
|
|
@@ -118,11 +118,11 @@ export function ChartView({ node, props }) {
|
|
|
118
118
|
const t = useTranslations('genui');
|
|
119
119
|
const focus = useFocus();
|
|
120
120
|
const locale = useLocale();
|
|
121
|
+
const number = useMemo(() => new Intl.NumberFormat(locale), [locale]);
|
|
122
|
+
const compact = useMemo(() => new Intl.NumberFormat(locale, { notation: 'compact' }), [locale]);
|
|
121
123
|
// A streamed pie arrives before its slices resolve (the parent line comes first). Hold its space until one lands.
|
|
122
124
|
if (node.type === 'PieChart' && kids(props.slices).length === 0)
|
|
123
125
|
return GenuiPending(node);
|
|
124
|
-
const number = new Intl.NumberFormat(locale);
|
|
125
|
-
const compact = new Intl.NumberFormat(locale, { notation: 'compact' });
|
|
126
126
|
const format = (value) => (typeof value === 'number' ? number.format(value) : value == null ? '—' : String(value));
|
|
127
127
|
// The tooltip row of `ChartTooltipContent`, with the table's number format.
|
|
128
128
|
const tooltip = (_jsx(ChartTooltipContent, { hideLabel: node.type === 'PieChart', formatter: (value, name, item) => (_jsxs(_Fragment, { children: [_jsx("span", { className: "size-2.5 shrink-0 rounded-xs", style: { backgroundColor: item.payload?.fill ?? item.color } }), _jsxs("span", { className: "flex flex-1 items-center justify-between gap-2 leading-none", children: [_jsx("span", { className: "text-muted-foreground", children: name }), _jsx("span", { className: "text-foreground font-mono font-medium tabular-nums", children: format(value) })] })] })) }));
|
|
@@ -160,7 +160,8 @@ export function ChartView({ node, props }) {
|
|
|
160
160
|
/** The chart's values as text: the Show data dialog's table. A missing value stays a dash, never a zero. */
|
|
161
161
|
export function ChartDataTable({ node }) {
|
|
162
162
|
const t = useTranslations('genui');
|
|
163
|
-
const
|
|
163
|
+
const locale = useLocale();
|
|
164
|
+
const number = useMemo(() => new Intl.NumberFormat(locale), [locale]);
|
|
164
165
|
const format = (value) => (typeof value === 'number' ? number.format(value) : value == null ? '—' : String(value));
|
|
165
166
|
const { props } = node;
|
|
166
167
|
let head;
|
package/dist/primitives/map.js
CHANGED
|
@@ -163,7 +163,8 @@ function MapMarker({ longitude, latitude, label, children, ...markerOptions }) {
|
|
|
163
163
|
marker.setLngLat([longitude, latitude]);
|
|
164
164
|
}
|
|
165
165
|
}, [marker, longitude, latitude]);
|
|
166
|
-
|
|
166
|
+
const markerContextValue = useMemo(() => ({ marker, map }), [marker, map]);
|
|
167
|
+
return _jsx(MarkerContext.Provider, { value: markerContextValue, children: children });
|
|
167
168
|
}
|
|
168
169
|
function MarkerContent({ children, className }) {
|
|
169
170
|
const { marker } = useMarkerContext();
|
|
@@ -22,10 +22,12 @@ const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
|
22
22
|
const PreviewImageContent = React.forwardRef(({ className, fileContent, fileName, ...props }, ref) => {
|
|
23
23
|
const [zoomLevel, setZoomLevel] = React.useState(DEFAULT_ZOOM);
|
|
24
24
|
const [transformOrigin, setTransformOrigin] = React.useState(DEFAULT_ORIGIN);
|
|
25
|
-
React.
|
|
25
|
+
const [zoomedContent, setZoomedContent] = React.useState(fileContent);
|
|
26
|
+
if (fileContent !== zoomedContent) {
|
|
27
|
+
setZoomedContent(fileContent);
|
|
26
28
|
setZoomLevel(DEFAULT_ZOOM);
|
|
27
29
|
setTransformOrigin(DEFAULT_ORIGIN);
|
|
28
|
-
}
|
|
30
|
+
}
|
|
29
31
|
const getTransformOrigin = (event) => {
|
|
30
32
|
const rect = event.currentTarget.getBoundingClientRect();
|
|
31
33
|
if (!rect.width || !rect.height) {
|
|
@@ -59,7 +59,7 @@ export const useAutosizeTextArea = ({ textAreaRef, triggerAutoSize, maxHeight =
|
|
|
59
59
|
clearTimeout(resizeTimeoutRef.current);
|
|
60
60
|
}
|
|
61
61
|
};
|
|
62
|
-
}, [textAreaRef
|
|
62
|
+
}, [textAreaRef, triggerAutoSize, minHeight, maxHeight, currentHeight, init]);
|
|
63
63
|
};
|
|
64
64
|
export const Textarea = React.forwardRef(({ maxHeight = Number.MAX_SAFE_INTEGER, minHeight = 52, className, onChange, value, variant: _variant, ...props }, ref) => {
|
|
65
65
|
const textAreaRef = React.useRef(null);
|
|
@@ -19,25 +19,23 @@ import { shouldTypeOnChange, TYPE_SPEED_MS } from './typed-title-logic.js';
|
|
|
19
19
|
import { TypingAnimation } from './typing-animation.js';
|
|
20
20
|
import { cn } from '../lib/utils.js';
|
|
21
21
|
import { useReducedMotion } from 'motion/react';
|
|
22
|
-
import { useCallback,
|
|
22
|
+
import { useCallback, useState } from 'react';
|
|
23
23
|
export { TYPE_SPEED_MS };
|
|
24
24
|
export function useTypeOnChange(text) {
|
|
25
|
-
// The last value this row DISPLAYED
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
|
|
29
|
-
const previousRef = useRef(null);
|
|
25
|
+
// The last value this row DISPLAYED. It updates in the same render pass that
|
|
26
|
+
// decides to animate, or a second change arriving mid-type compares against
|
|
27
|
+
// a stale value and is missed.
|
|
28
|
+
const [previous, setPrevious] = useState(null);
|
|
30
29
|
const [isTyping, setIsTyping] = useState(false);
|
|
31
30
|
const [runId, setRunId] = useState(0);
|
|
32
31
|
const reduceMotion = !!useReducedMotion();
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}, [text, reduceMotion]);
|
|
32
|
+
if (previous !== text) {
|
|
33
|
+
setPrevious(text);
|
|
34
|
+
if (shouldTypeOnChange({ previous, next: text, reduceMotion })) {
|
|
35
|
+
setIsTyping(true);
|
|
36
|
+
setRunId((id) => id + 1);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
41
39
|
const stop = useCallback(() => setIsTyping(false), []);
|
|
42
40
|
return { isTyping, runId, stop };
|
|
43
41
|
}
|
|
@@ -34,12 +34,14 @@ export function TypingAnimation({ children, words, className, duration = 100, ty
|
|
|
34
34
|
const deletingSpeed = deleteSpeed ?? typingSpeed / 2;
|
|
35
35
|
const shouldStart = startOnView ? isInView : true;
|
|
36
36
|
const animationSourceKey = useMemo(() => (words ? words.join('\u0000') : (children ?? '')), [words, children]);
|
|
37
|
-
|
|
37
|
+
const [seenSourceKey, setSeenSourceKey] = useState(animationSourceKey);
|
|
38
|
+
if (animationSourceKey !== seenSourceKey) {
|
|
39
|
+
setSeenSourceKey(animationSourceKey);
|
|
38
40
|
setDisplayedText('');
|
|
39
41
|
setCurrentWordIndex(0);
|
|
40
42
|
setCurrentCharIndex(0);
|
|
41
43
|
setPhase('typing');
|
|
42
|
-
}
|
|
44
|
+
}
|
|
43
45
|
useEffect(() => {
|
|
44
46
|
let timeout = null;
|
|
45
47
|
if (shouldStart && wordsToAnimate.length > 0) {
|
|
@@ -45,7 +45,12 @@ export function AgentSelector({ agents, selectedAgent, onSelect, disabled = fals
|
|
|
45
45
|
const [search, setSearch] = useState('');
|
|
46
46
|
const { offeredAgents, agentLabels } = useUiHostConfig();
|
|
47
47
|
// A host that lists its agents (`offeredAgents`) offers only those; it names them with `agentLabels`.
|
|
48
|
-
const offered = useMemo(() =>
|
|
48
|
+
const offered = useMemo(() => {
|
|
49
|
+
if (!offeredAgents)
|
|
50
|
+
return agents;
|
|
51
|
+
const offeredNames = new Set(offeredAgents);
|
|
52
|
+
return agents.filter((a) => offeredNames.has(a.name));
|
|
53
|
+
}, [agents, offeredAgents]);
|
|
49
54
|
const primaryAgents = useMemo(() => composerSelectableAgents(offered), [offered]);
|
|
50
55
|
const label = (name) => agentLabels?.[name] ?? (isMetaAgentName(name) ? META_AGENT_DISPLAY_NAME : capitalizeWords(name));
|
|
51
56
|
// A `flash` state, a `prevAgentRef` feeding it, two effects and a 400ms
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
3
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
4
4
|
import { SessionOverridesComposer } from '../overrides/session-overrides-composer.js';
|
|
5
5
|
import { SessionChatInput, } from './session-chat-input.js';
|
|
6
6
|
import { useProjectConfig, useRuntimeAgents, useRuntimeCommands, useRuntimeConfig, useRuntimeProviders, useSessionModelSelection } from '@kortix/sdk/react';
|
|
@@ -103,10 +103,11 @@ export function ComposerChatInput({ onSend, onCommand, sessionId, projectId, isB
|
|
|
103
103
|
useEffect(() => {
|
|
104
104
|
onAgentSelectionChange?.(selectedAgentName);
|
|
105
105
|
}, [onAgentSelectionChange, selectedAgentName]);
|
|
106
|
-
|
|
106
|
+
// Read only by `options()` at send time, so a ref: a commit needs no render.
|
|
107
|
+
const newSessionScopeRef = useRef(null);
|
|
107
108
|
const [newProviderSecretPools, setNewProviderSecretPools] = useState({});
|
|
108
109
|
const handleCommittedScope = useCallback((commit) => {
|
|
109
|
-
|
|
110
|
+
newSessionScopeRef.current = commit ? { agentName: selectedAgentName, commit } : null;
|
|
110
111
|
}, [selectedAgentName]);
|
|
111
112
|
// The axes a session can override that have no control of their own —
|
|
112
113
|
// secrets, connectors, sandbox. Agent, model and effort are NOT passed: this
|
|
@@ -126,6 +127,7 @@ export function ComposerChatInput({ onSend, onCommand, sessionId, projectId, isB
|
|
|
126
127
|
o.model = local.model.currentKey;
|
|
127
128
|
if (local.model.variant.current)
|
|
128
129
|
o.variant = local.model.variant.current;
|
|
130
|
+
const newSessionScope = newSessionScopeRef.current;
|
|
129
131
|
if (!sessionId && newSessionScope && newSessionScope.agentName === selectedAgentName) {
|
|
130
132
|
o.scope = newSessionScope.commit;
|
|
131
133
|
}
|
|
@@ -51,11 +51,7 @@ export function extractReplyQuotes(text) {
|
|
|
51
51
|
const { quotes } = parseReplyContexts(text);
|
|
52
52
|
if (quotes.length === 0)
|
|
53
53
|
return { quotes: [], text };
|
|
54
|
-
const unique = [];
|
|
55
|
-
for (const quote of quotes) {
|
|
56
|
-
if (quote && !unique.includes(quote))
|
|
57
|
-
unique.push(quote);
|
|
58
|
-
}
|
|
54
|
+
const unique = [...new Set(quotes.filter(Boolean))];
|
|
59
55
|
return { quotes: unique, text: stripReplyContexts(text) };
|
|
60
56
|
}
|
|
61
57
|
/**
|
|
@@ -96,12 +92,16 @@ export function mergeComposerQuotes(restored, current) {
|
|
|
96
92
|
* returns `current` itself.
|
|
97
93
|
*/
|
|
98
94
|
export function restoreComposerQuotes(current, texts, makeId) {
|
|
95
|
+
const currentByText = new Map();
|
|
96
|
+
for (const quote of current)
|
|
97
|
+
if (!currentByText.has(quote.text))
|
|
98
|
+
currentByText.set(quote.text, quote);
|
|
99
99
|
const restored = [];
|
|
100
100
|
for (const raw of texts) {
|
|
101
101
|
const text = raw.trim();
|
|
102
102
|
if (!text || restored.some((quote) => quote.text === text))
|
|
103
103
|
continue;
|
|
104
|
-
restored.push(
|
|
104
|
+
restored.push(currentByText.get(text) ?? { id: makeId(), text });
|
|
105
105
|
}
|
|
106
106
|
if (restored.length === 0)
|
|
107
107
|
return current;
|
|
@@ -249,7 +249,8 @@ export function planQuoteRequests({ requests, appliedIds, }) {
|
|
|
249
249
|
* itself when nothing matches, so a no-op ack does not re-render.
|
|
250
250
|
*/
|
|
251
251
|
export function acknowledgeQuoteRequests(requests, ids) {
|
|
252
|
-
const
|
|
252
|
+
const acked = new Set(ids);
|
|
253
|
+
const remaining = requests.filter((request) => !acked.has(request.id));
|
|
253
254
|
return remaining.length === requests.length ? requests : remaining;
|
|
254
255
|
}
|
|
255
256
|
/**
|
|
@@ -76,14 +76,14 @@ export function deserializeDraft(raw, currentUserId) {
|
|
|
76
76
|
if (!Array.isArray(candidate.files))
|
|
77
77
|
return null;
|
|
78
78
|
const legacy = liftLegacyQuoteNodes(candidate.doc);
|
|
79
|
-
const quotes =
|
|
79
|
+
const quotes = new Set();
|
|
80
80
|
const stored = Array.isArray(candidate.quotes) ? candidate.quotes : [];
|
|
81
81
|
for (const quote of [...stored, ...legacy.quotes]) {
|
|
82
82
|
if (typeof quote !== 'string')
|
|
83
83
|
continue;
|
|
84
84
|
const text = quote.trim();
|
|
85
|
-
if (text
|
|
86
|
-
quotes.
|
|
85
|
+
if (text)
|
|
86
|
+
quotes.add(text);
|
|
87
87
|
}
|
|
88
88
|
// Only `{ id, text }` with both set crosses back; anything else in storage is dropped.
|
|
89
89
|
const storedPastes = Array.isArray(candidate.pastes) ? candidate.pastes : [];
|
|
@@ -101,7 +101,7 @@ export function deserializeDraft(raw, currentUserId) {
|
|
|
101
101
|
u: candidate.u,
|
|
102
102
|
doc: legacy.doc,
|
|
103
103
|
files: candidate.files.filter(isRemote),
|
|
104
|
-
quotes,
|
|
104
|
+
quotes: [...quotes],
|
|
105
105
|
pastes,
|
|
106
106
|
uploads,
|
|
107
107
|
};
|
|
@@ -19,12 +19,13 @@ export function PastedTextCopy({ text }) {
|
|
|
19
19
|
// The toolbar `ButtonGroup`'s look: `size-7` on the `secondary` fill, as `CloseButton`.
|
|
20
20
|
return (_jsx(CopyButton, { code: text, size: "md", className: "bg-secondary hover:bg-secondary/90 shrink-0", label: t.raw('texte21f935f11d7') }));
|
|
21
21
|
}
|
|
22
|
+
const graphemeSegmenter = typeof Intl !== 'undefined' && 'Segmenter' in Intl ? new Intl.Segmenter() : null;
|
|
22
23
|
/** Word and character counts for the header. Characters are what the user sees: graphemes, else code points. */
|
|
23
24
|
export function pastedTextCounts(text) {
|
|
24
25
|
const words = text.trim() ? text.trim().split(/\s+/).length : 0;
|
|
25
26
|
let chars = 0;
|
|
26
|
-
if (
|
|
27
|
-
for (const _segment of
|
|
27
|
+
if (graphemeSegmenter) {
|
|
28
|
+
for (const _segment of graphemeSegmenter.segment(text))
|
|
28
29
|
chars++;
|
|
29
30
|
}
|
|
30
31
|
else
|
|
@@ -18,9 +18,10 @@ export const useQueuedDraftStore = create((set) => ({
|
|
|
18
18
|
}),
|
|
19
19
|
remove: (sessionId, clientMessageIds) => set((s) => {
|
|
20
20
|
const drafts = s.bySession[sessionId];
|
|
21
|
-
|
|
21
|
+
const ids = new Set(clientMessageIds);
|
|
22
|
+
if (!drafts?.some((d) => ids.has(d.clientMessageId)))
|
|
22
23
|
return s;
|
|
23
|
-
return withSession(s, sessionId, drafts.filter((d) => !
|
|
24
|
+
return withSession(s, sessionId, drafts.filter((d) => !ids.has(d.clientMessageId)));
|
|
24
25
|
}),
|
|
25
26
|
prune: (sessionId, listedClientMessageIds) => set((s) => {
|
|
26
27
|
const drafts = s.bySession[sessionId];
|
|
@@ -33,7 +33,7 @@ export declare function ReminderFacts({ reminder, now, className, }: {
|
|
|
33
33
|
now: number;
|
|
34
34
|
className?: string;
|
|
35
35
|
}): import("react").JSX.Element;
|
|
36
|
-
/**
|
|
36
|
+
/** Retry a failed run, pause or resume, remove, and the link into the Reminders tab. */
|
|
37
37
|
export declare function ReminderActions({ reminder, controls, manageHref, onNavigate, className, }: {
|
|
38
38
|
reminder: SessionReminder;
|
|
39
39
|
controls: ReminderControls;
|
|
@@ -43,11 +43,14 @@ export declare function ReminderActions({ reminder, controls, manageHref, onNavi
|
|
|
43
43
|
}): import("react").JSX.Element;
|
|
44
44
|
export interface ReminderControls {
|
|
45
45
|
pending: boolean;
|
|
46
|
+
running: boolean;
|
|
47
|
+
/** Fire the reminder once now. */
|
|
48
|
+
run: (reminder: SessionReminder) => void;
|
|
46
49
|
setEnabled: (reminder: SessionReminder, enabled: boolean) => void;
|
|
47
50
|
requestRemove: (reminder: SessionReminder) => void;
|
|
48
51
|
}
|
|
49
52
|
/**
|
|
50
|
-
* The session's reminders with pause, resume and remove. Remove asks first:
|
|
53
|
+
* The session's reminders with run, pause, resume and remove. Remove asks first:
|
|
51
54
|
* render `confirm` once next to whatever calls `requestRemove`.
|
|
52
55
|
*/
|
|
53
56
|
export declare function useReminderControls(projectId: string | null, sessionId: string | null | undefined): {
|
|
@@ -59,6 +62,7 @@ export declare function useReminderControls(projectId: string | null, sessionId:
|
|
|
59
62
|
remove: import("@tanstack/react-query").UseMutationResult<{
|
|
60
63
|
ok: boolean;
|
|
61
64
|
}, Error, string, unknown>;
|
|
65
|
+
run: import("@tanstack/react-query").UseMutationResult<SessionReminder, Error, string, unknown>;
|
|
62
66
|
data: {
|
|
63
67
|
reminders: SessionReminder[];
|
|
64
68
|
};
|
|
@@ -96,6 +100,7 @@ export declare function useReminderControls(projectId: string | null, sessionId:
|
|
|
96
100
|
remove: import("@tanstack/react-query").UseMutationResult<{
|
|
97
101
|
ok: boolean;
|
|
98
102
|
}, Error, string, unknown>;
|
|
103
|
+
run: import("@tanstack/react-query").UseMutationResult<SessionReminder, Error, string, unknown>;
|
|
99
104
|
data: {
|
|
100
105
|
reminders: SessionReminder[];
|
|
101
106
|
};
|
|
@@ -133,6 +138,7 @@ export declare function useReminderControls(projectId: string | null, sessionId:
|
|
|
133
138
|
remove: import("@tanstack/react-query").UseMutationResult<{
|
|
134
139
|
ok: boolean;
|
|
135
140
|
}, Error, string, unknown>;
|
|
141
|
+
run: import("@tanstack/react-query").UseMutationResult<SessionReminder, Error, string, unknown>;
|
|
136
142
|
data: undefined;
|
|
137
143
|
error: Error;
|
|
138
144
|
isError: true;
|
|
@@ -168,6 +174,7 @@ export declare function useReminderControls(projectId: string | null, sessionId:
|
|
|
168
174
|
remove: import("@tanstack/react-query").UseMutationResult<{
|
|
169
175
|
ok: boolean;
|
|
170
176
|
}, Error, string, unknown>;
|
|
177
|
+
run: import("@tanstack/react-query").UseMutationResult<SessionReminder, Error, string, unknown>;
|
|
171
178
|
data: undefined;
|
|
172
179
|
error: null;
|
|
173
180
|
isError: false;
|
|
@@ -203,6 +210,7 @@ export declare function useReminderControls(projectId: string | null, sessionId:
|
|
|
203
210
|
remove: import("@tanstack/react-query").UseMutationResult<{
|
|
204
211
|
ok: boolean;
|
|
205
212
|
}, Error, string, unknown>;
|
|
213
|
+
run: import("@tanstack/react-query").UseMutationResult<SessionReminder, Error, string, unknown>;
|
|
206
214
|
data: undefined;
|
|
207
215
|
error: null;
|
|
208
216
|
isError: false;
|
|
@@ -238,6 +246,7 @@ export declare function useReminderControls(projectId: string | null, sessionId:
|
|
|
238
246
|
remove: import("@tanstack/react-query").UseMutationResult<{
|
|
239
247
|
ok: boolean;
|
|
240
248
|
}, Error, string, unknown>;
|
|
249
|
+
run: import("@tanstack/react-query").UseMutationResult<SessionReminder, Error, string, unknown>;
|
|
241
250
|
data: {
|
|
242
251
|
reminders: SessionReminder[];
|
|
243
252
|
};
|