@opengeni/react 7.4.0-canary.36844267522001 → 7.4.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/README.md +0 -10
- package/dist/artifacts-document.js +2 -3
- package/dist/artifacts-presentation.js +2 -3
- package/dist/artifacts-spreadsheet.js +2 -2
- package/dist/artifacts.d.ts +0 -1
- package/dist/artifacts.js +1402 -505
- package/dist/artifacts.js.map +1 -1
- package/dist/{browser-viewer-AJO7LMVE.js → browser-viewer-2E6R2Y4W.js} +2 -2
- package/dist/{chunk-WUISZ3WU.js → chunk-3E2AITTZ.js} +28 -32
- package/dist/{chunk-WUISZ3WU.js.map → chunk-3E2AITTZ.js.map} +1 -1
- package/dist/{chunk-Y2PRMYLC.js → chunk-DUEBTL3N.js} +3 -4
- package/dist/{chunk-Y2PRMYLC.js.map → chunk-DUEBTL3N.js.map} +1 -1
- package/dist/{chunk-7UAMYXJY.js → chunk-KNDIXZN6.js} +18 -25
- package/dist/{chunk-7UAMYXJY.js.map → chunk-KNDIXZN6.js.map} +1 -1
- package/dist/{chunk-XVYRQ4PK.js → chunk-L4OSXQ6H.js} +116 -277
- package/dist/chunk-L4OSXQ6H.js.map +1 -0
- package/dist/{chunk-7B44WVGH.js → chunk-S5JQ4R22.js} +12 -31
- package/dist/chunk-S5JQ4R22.js.map +1 -0
- package/dist/{chunk-A4UJB2MM.js → chunk-SEEVCT36.js} +2 -2
- package/dist/chunk-UGMKPUEM.js +299 -0
- package/dist/chunk-UGMKPUEM.js.map +1 -0
- package/dist/{chunk-OQVBTOBJ.js → chunk-USXVQACU.js} +3 -3
- package/dist/{chunk-ASCSKOWU.js → chunk-V2ABIVYJ.js} +3 -50
- package/dist/chunk-V2ABIVYJ.js.map +1 -0
- package/dist/{chunk-UQUR5WG5.js → chunk-X4HIN6TV.js} +157 -66
- package/dist/chunk-X4HIN6TV.js.map +1 -0
- package/dist/{chunk-QLG6W33X.js → chunk-XEJEOAOV.js} +35 -46
- package/dist/chunk-XEJEOAOV.js.map +1 -0
- package/dist/components/artifacts/editable-artifact-ui.d.ts +1 -2
- package/dist/components/artifacts/index.d.ts +0 -7
- package/dist/components/message-timeline.d.ts +1 -7
- package/dist/components/open-geni-links.d.ts +0 -16
- package/dist/components/session-conversation.d.ts +1 -13
- package/dist/{computer-viewer-NB6O6BTV.js → computer-viewer-WMJE6OA3.js} +2 -2
- package/dist/connect.js +1 -2
- package/dist/connect.js.map +1 -1
- package/dist/hooks/latest-question.d.ts +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.js +12 -22
- package/dist/index.js.map +1 -1
- package/dist/interaction.js +2 -2
- package/dist/{latest-question-3HGQUI2E.js → latest-question-QB4EUCW5.js} +2 -2
- package/dist/{markdown-table-layout-QXSLK4BY.js → markdown-table-layout-PFUEZ2U4.js} +5 -37
- package/dist/markdown-table-layout-PFUEZ2U4.js.map +1 -0
- package/dist/session-ui.d.ts +2 -3
- package/dist/session-ui.js +9 -18
- package/dist/session-ui.js.map +1 -1
- package/dist/session.js +2 -2
- package/dist/sites.js +289 -4
- package/dist/sites.js.map +1 -1
- package/package.json +3 -3
- package/src/artifacts.ts +0 -37
- package/src/components/artifacts/editable-artifact-ui.tsx +1 -3
- package/src/components/artifacts/editable-artifact-workbench.tsx +2 -5
- package/src/components/artifacts/editable-document.tsx +36 -34
- package/src/components/artifacts/editable-presentation.tsx +16 -21
- package/src/components/artifacts/index.ts +0 -41
- package/src/components/browser-viewer.tsx +20 -59
- package/src/components/computer-viewer.tsx +23 -51
- package/src/components/markdown-table-layout.ts +5 -49
- package/src/components/markdown.tsx +2 -5
- package/src/components/message-timeline.tsx +7 -59
- package/src/components/open-geni-links.tsx +0 -24
- package/src/components/session-conversation.tsx +20 -120
- package/src/index.ts +0 -7
- package/src/session-ui.ts +0 -7
- package/src/timeline/projection.ts +4 -54
- package/styles/compiled.css +0 -220
- package/dist/chat-interactive-block-VAGABN7J.js +0 -11
- package/dist/chunk-5CVXZA3Y.js +0 -292
- package/dist/chunk-5CVXZA3Y.js.map +0 -1
- package/dist/chunk-7B44WVGH.js.map +0 -1
- package/dist/chunk-ASCSKOWU.js.map +0 -1
- package/dist/chunk-QLG6W33X.js.map +0 -1
- package/dist/chunk-RAIQYITC.js +0 -1772
- package/dist/chunk-RAIQYITC.js.map +0 -1
- package/dist/chunk-SCOTPE2I.js +0 -589
- package/dist/chunk-SCOTPE2I.js.map +0 -1
- package/dist/chunk-UQUR5WG5.js.map +0 -1
- package/dist/chunk-WEHMPOXK.js +0 -39
- package/dist/chunk-WEHMPOXK.js.map +0 -1
- package/dist/chunk-XCHWDJ22.js +0 -107
- package/dist/chunk-XCHWDJ22.js.map +0 -1
- package/dist/chunk-XVYRQ4PK.js.map +0 -1
- package/dist/components/artifacts/artifact-chrome.d.ts +0 -120
- package/dist/components/artifacts/artifact-sandbox.d.ts +0 -27
- package/dist/components/artifacts/chat-interactive-block.d.ts +0 -29
- package/dist/components/artifacts/deferred-chat-media.d.ts +0 -15
- package/dist/components/artifacts/editable-artifact-view.d.ts +0 -46
- package/dist/components/artifacts/latest-task-runner.d.ts +0 -15
- package/dist/components/artifacts/session-artifact-viewer.d.ts +0 -39
- package/dist/components/artifacts/site-view.d.ts +0 -23
- package/dist/components/timeline-pill-geometry.d.ts +0 -6
- package/dist/components/timeline-pill-placement.d.ts +0 -18
- package/dist/computer-viewer-NB6O6BTV.js.map +0 -1
- package/dist/markdown-table-layout-QXSLK4BY.js.map +0 -1
- package/dist/timeline-pill-geometry-2G6EK47V.js +0 -73
- package/dist/timeline-pill-geometry-2G6EK47V.js.map +0 -1
- package/src/components/artifacts/artifact-chrome.tsx +0 -413
- package/src/components/artifacts/artifact-sandbox.tsx +0 -185
- package/src/components/artifacts/chat-interactive-block.tsx +0 -260
- package/src/components/artifacts/deferred-chat-media.tsx +0 -67
- package/src/components/artifacts/editable-artifact-view.tsx +0 -187
- package/src/components/artifacts/latest-task-runner.ts +0 -49
- package/src/components/artifacts/session-artifact-viewer.tsx +0 -376
- package/src/components/artifacts/site-view.tsx +0 -116
- package/src/components/timeline-pill-geometry.ts +0 -112
- package/src/components/timeline-pill-placement.ts +0 -81
- /package/dist/{browser-viewer-AJO7LMVE.js.map → browser-viewer-2E6R2Y4W.js.map} +0 -0
- /package/dist/{chunk-A4UJB2MM.js.map → chunk-SEEVCT36.js.map} +0 -0
- /package/dist/{chunk-OQVBTOBJ.js.map → chunk-USXVQACU.js.map} +0 -0
- /package/dist/{chat-interactive-block-VAGABN7J.js.map → computer-viewer-WMJE6OA3.js.map} +0 -0
- /package/dist/{latest-question-3HGQUI2E.js.map → latest-question-QB4EUCW5.js.map} +0 -0
|
@@ -60,12 +60,10 @@ export function EditableArtifactMessage({
|
|
|
60
60
|
title,
|
|
61
61
|
detail,
|
|
62
62
|
retry,
|
|
63
|
-
retryLabel = "Retry",
|
|
64
63
|
}: {
|
|
65
64
|
title: string;
|
|
66
65
|
detail: string;
|
|
67
66
|
retry?: (() => void) | undefined;
|
|
68
|
-
retryLabel?: string | undefined;
|
|
69
67
|
}) {
|
|
70
68
|
return (
|
|
71
69
|
<div className="grid h-full min-h-56 place-items-center bg-og-bg p-6 text-center">
|
|
@@ -78,7 +76,7 @@ export function EditableArtifactMessage({
|
|
|
78
76
|
onClick={retry}
|
|
79
77
|
className="mt-3 rounded-og-sm border border-og-primary-border bg-og-primary text-og-primary-fg px-3 py-1.5 text-og-sm font-medium hover:bg-og-primary-hover outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent"
|
|
80
78
|
>
|
|
81
|
-
|
|
79
|
+
Retry
|
|
82
80
|
</button>
|
|
83
81
|
) : null}
|
|
84
82
|
</div>
|
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
} from "@opengeni/sdk/editable-artifacts";
|
|
7
7
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
8
8
|
|
|
9
|
-
import { useArtifactLabels } from "./artifact-chrome";
|
|
10
9
|
import { EditableArtifactMessage } from "./editable-artifact-ui";
|
|
11
10
|
import {
|
|
12
11
|
EditableDocumentArtifactSurface,
|
|
@@ -134,7 +133,6 @@ export function EditableArtifactWorkbenchHost({
|
|
|
134
133
|
}, [retryEpoch, sessionKey]);
|
|
135
134
|
|
|
136
135
|
const retry = useCallback(() => setRetryEpoch((value) => value + 1), []);
|
|
137
|
-
const labels = useArtifactLabels();
|
|
138
136
|
const currentError = state.key === sessionKey ? state.error : null;
|
|
139
137
|
if (state.key === sessionKey && state.session) {
|
|
140
138
|
return (
|
|
@@ -148,10 +146,9 @@ export function EditableArtifactWorkbenchHost({
|
|
|
148
146
|
}
|
|
149
147
|
return (
|
|
150
148
|
<EditableArtifactMessage
|
|
151
|
-
title={currentError ?
|
|
152
|
-
detail={currentError?.message ??
|
|
149
|
+
title={currentError ? "Could not open this artifact" : "Opening artifact"}
|
|
150
|
+
detail={currentError?.message ?? "Starting the secure editing session…"}
|
|
153
151
|
retry={currentError ? retry : undefined}
|
|
154
|
-
retryLabel={labels.retry}
|
|
155
152
|
/>
|
|
156
153
|
);
|
|
157
154
|
}
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
type EditableArtifactSession,
|
|
10
10
|
} from "@opengeni/sdk/editable-artifacts";
|
|
11
11
|
import { type ReactNode, useCallback, useEffect, useRef, useState } from "react";
|
|
12
|
-
import { useLatestTaskRunner } from "./latest-task-runner";
|
|
13
12
|
|
|
14
13
|
import {
|
|
15
14
|
DocumentProjectionArtifactSurface,
|
|
@@ -88,7 +87,6 @@ export function EditableDocumentArtifactSurface({
|
|
|
88
87
|
error: null,
|
|
89
88
|
});
|
|
90
89
|
const loadGeneration = useRef(0);
|
|
91
|
-
const scheduleLoad = useLatestTaskRunner(session);
|
|
92
90
|
const commandStateRef = useRef<DocumentCommandState | null>(null);
|
|
93
91
|
if (commandStateRef.current?.session !== session) {
|
|
94
92
|
commandStateRef.current = {
|
|
@@ -109,41 +107,45 @@ export function EditableDocumentArtifactSurface({
|
|
|
109
107
|
? { ...current, loading: true, error: null }
|
|
110
108
|
: { session, projection: null, loading: true, error: null },
|
|
111
109
|
);
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
110
|
+
void composeDocumentEditorProjection(session).then(
|
|
111
|
+
(projection) => {
|
|
112
|
+
if (
|
|
113
|
+
cancelled ||
|
|
114
|
+
generation !== loadGeneration.current ||
|
|
115
|
+
commandStateRef.current !== commandState
|
|
116
|
+
) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const nextParagraphText = paragraphTextById(projection);
|
|
120
|
+
for (const [localId, canonicalId] of commandState.optimisticParagraphIds) {
|
|
121
|
+
if (nextParagraphText.has(canonicalId)) continue;
|
|
122
|
+
const optimisticText =
|
|
123
|
+
commandState.paragraphText.get(canonicalId) ?? commandState.paragraphText.get(localId);
|
|
124
|
+
if (optimisticText !== undefined) nextParagraphText.set(canonicalId, optimisticText);
|
|
125
|
+
}
|
|
126
|
+
commandState.paragraphText = nextParagraphText;
|
|
127
|
+
setState({ session, projection, loading: false, error: null });
|
|
128
|
+
},
|
|
129
|
+
(cause) => {
|
|
130
|
+
if (
|
|
131
|
+
cancelled ||
|
|
132
|
+
generation !== loadGeneration.current ||
|
|
133
|
+
commandStateRef.current !== commandState
|
|
134
|
+
) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
setState({
|
|
138
|
+
session,
|
|
139
|
+
projection: null,
|
|
140
|
+
loading: false,
|
|
141
|
+
error: asEditableArtifactError(cause, "Could not open this document"),
|
|
142
|
+
});
|
|
143
|
+
},
|
|
144
|
+
);
|
|
143
145
|
return () => {
|
|
144
146
|
cancelled = true;
|
|
145
147
|
};
|
|
146
|
-
}, [commandState, invalidator, retryEpoch,
|
|
148
|
+
}, [commandState, invalidator, retryEpoch, session]);
|
|
147
149
|
|
|
148
150
|
const refresh = useCallback(() => setRetryEpoch((value) => value + 1), []);
|
|
149
151
|
const writable = !readOnly && view.writable;
|
|
@@ -33,7 +33,6 @@ import {
|
|
|
33
33
|
type PresentationSlideProjection,
|
|
34
34
|
} from "./presentation-editor";
|
|
35
35
|
import { ArtifactSurface } from "./artifact-surface";
|
|
36
|
-
import { useLatestTaskRunner } from "./latest-task-runner";
|
|
37
36
|
import {
|
|
38
37
|
asEditableArtifactError,
|
|
39
38
|
editableArtifactAccessRevoked,
|
|
@@ -106,35 +105,31 @@ export function EditablePresentationArtifactSurface({
|
|
|
106
105
|
error: null,
|
|
107
106
|
});
|
|
108
107
|
const loadGeneration = useRef(0);
|
|
109
|
-
const scheduleLoad = useLatestTaskRunner(session);
|
|
110
108
|
const sceneNodes = useRef(new Map<string, PresentationArtifactEditorSceneNode>());
|
|
111
109
|
|
|
112
110
|
useEffect(() => {
|
|
113
111
|
const generation = ++loadGeneration.current;
|
|
114
112
|
let cancelled = false;
|
|
115
113
|
setState((current) => ({ ...current, loading: true, error: null }));
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
(composed)
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
(
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
},
|
|
132
|
-
);
|
|
133
|
-
});
|
|
114
|
+
void composePresentationEditorProjection(session).then(
|
|
115
|
+
(composed) => {
|
|
116
|
+
if (cancelled || generation !== loadGeneration.current) return;
|
|
117
|
+
sceneNodes.current = new Map(composed.sceneNodes);
|
|
118
|
+
setState({ composed, loading: false, error: null });
|
|
119
|
+
},
|
|
120
|
+
(cause) => {
|
|
121
|
+
if (cancelled || generation !== loadGeneration.current) return;
|
|
122
|
+
setState({
|
|
123
|
+
composed: null,
|
|
124
|
+
loading: false,
|
|
125
|
+
error: asEditableArtifactError(cause, "Could not open this presentation"),
|
|
126
|
+
});
|
|
127
|
+
},
|
|
128
|
+
);
|
|
134
129
|
return () => {
|
|
135
130
|
cancelled = true;
|
|
136
131
|
};
|
|
137
|
-
}, [invalidator, retryEpoch,
|
|
132
|
+
}, [invalidator, retryEpoch, session]);
|
|
138
133
|
|
|
139
134
|
const refresh = useCallback(() => setRetryEpoch((value) => value + 1), []);
|
|
140
135
|
const writable = !readOnly && view.writable;
|
|
@@ -1,44 +1,3 @@
|
|
|
1
|
-
export {
|
|
2
|
-
ArtifactBadge,
|
|
3
|
-
ArtifactLabelsProvider,
|
|
4
|
-
DEFAULT_ARTIFACT_LABELS,
|
|
5
|
-
useArtifactLabels,
|
|
6
|
-
type ArtifactLabels,
|
|
7
|
-
ArtifactButton,
|
|
8
|
-
ArtifactLoading,
|
|
9
|
-
ArtifactProblem,
|
|
10
|
-
ArtifactSelect,
|
|
11
|
-
ArtifactViewerHeader,
|
|
12
|
-
artifactKindIcon,
|
|
13
|
-
artifactKindSubtitle,
|
|
14
|
-
artifactLoadErrorMessage,
|
|
15
|
-
artifactLoadErrorView,
|
|
16
|
-
type ArtifactKind,
|
|
17
|
-
type ArtifactLoadErrorKind,
|
|
18
|
-
type ArtifactLoadErrorView,
|
|
19
|
-
} from "./artifact-chrome";
|
|
20
|
-
export { ArtifactSandbox, type ArtifactSandboxProps } from "./artifact-sandbox";
|
|
21
|
-
export { DeferredChatMedia } from "./deferred-chat-media";
|
|
22
|
-
export {
|
|
23
|
-
ChatInteractiveBlock,
|
|
24
|
-
type ChatInteractiveBlockProps,
|
|
25
|
-
type SiteSnapshotClient,
|
|
26
|
-
type SiteToolBridgeFactory,
|
|
27
|
-
type SiteToolScope,
|
|
28
|
-
} from "./chat-interactive-block";
|
|
29
|
-
export { SiteView, type SiteViewProps } from "./site-view";
|
|
30
|
-
export {
|
|
31
|
-
EditableArtifactView,
|
|
32
|
-
type EditableArtifactRuntimes,
|
|
33
|
-
type EditableArtifactViewProps,
|
|
34
|
-
type OpenedEditableArtifact,
|
|
35
|
-
} from "./editable-artifact-view";
|
|
36
|
-
export {
|
|
37
|
-
SessionArtifactViewer,
|
|
38
|
-
type SessionArtifactTarget,
|
|
39
|
-
type SessionArtifactViewerLabels,
|
|
40
|
-
type SessionArtifactViewerProps,
|
|
41
|
-
} from "./session-artifact-viewer";
|
|
42
1
|
export {
|
|
43
2
|
ArtifactSurface,
|
|
44
3
|
type ArtifactModality,
|
|
@@ -208,11 +208,6 @@ export function BrowserViewer({
|
|
|
208
208
|
() => registry.relevantSessions.filter((session) => isLiveBrowser(session)),
|
|
209
209
|
[registry.relevantSessions],
|
|
210
210
|
);
|
|
211
|
-
const latestRelevantBrowser = registry.relevantSessions[0];
|
|
212
|
-
const unavailableBrowser =
|
|
213
|
-
latestRelevantBrowser?.lifecycle === "lost" || latestRelevantBrowser?.lifecycle === "failed"
|
|
214
|
-
? latestRelevantBrowser
|
|
215
|
-
: undefined;
|
|
216
211
|
const [selection, setSelection] = useState<BrowserSelection>(() =>
|
|
217
212
|
initialBrowserSessionId ? { sessionId: initialBrowserSessionId, pinned: true } : null,
|
|
218
213
|
);
|
|
@@ -774,8 +769,7 @@ export function BrowserViewer({
|
|
|
774
769
|
);
|
|
775
770
|
}
|
|
776
771
|
if (liveSessions.length === 0) {
|
|
777
|
-
if (renderEmpty
|
|
778
|
-
return <>{renderEmpty(() => createBrowser(), creating)}</>;
|
|
772
|
+
if (renderEmpty) return <>{renderEmpty(() => createBrowser(), creating)}</>;
|
|
779
773
|
return (
|
|
780
774
|
<div
|
|
781
775
|
className={cn("flex h-full min-h-0 items-center justify-center bg-og-bg p-6", className)}
|
|
@@ -784,22 +778,16 @@ export function BrowserViewer({
|
|
|
784
778
|
<span className="mx-auto grid size-10 place-items-center rounded-og-md border border-og-border bg-og-surface-1 text-og-fg-muted">
|
|
785
779
|
<Globe2Icon className="size-4.5" />
|
|
786
780
|
</span>
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
{attachedGenerationLoss
|
|
798
|
-
? "This Chrome profile is live again, but the previous browser cannot move to the new connection. Use Browser → New browser → Connected Chrome."
|
|
799
|
-
: "A browser appears here when this agent—or another agent in the workspace—opens one."}
|
|
800
|
-
</p>
|
|
801
|
-
</>
|
|
802
|
-
)}
|
|
781
|
+
<p className="mt-3 text-og-menu font-medium text-og-fg">
|
|
782
|
+
{attachedGenerationLoss
|
|
783
|
+
? "Chrome reconnected—open a fresh browser/desktop."
|
|
784
|
+
: "No browser open"}
|
|
785
|
+
</p>
|
|
786
|
+
<p className="mt-1 text-og-control leading-5 text-og-fg-muted">
|
|
787
|
+
{attachedGenerationLoss
|
|
788
|
+
? "This Chrome profile is live again, but the previous browser cannot move to the new connection. Use Browser → New browser → Connected Chrome."
|
|
789
|
+
: "A browser appears here when this agent—or another agent in the workspace—opens one."}
|
|
790
|
+
</p>
|
|
803
791
|
<BrowserLaunchMenu
|
|
804
792
|
attachedBridges={onlineAttachedBridges}
|
|
805
793
|
attachedDevices={attached.devices}
|
|
@@ -867,7 +855,6 @@ export function BrowserViewer({
|
|
|
867
855
|
/>
|
|
868
856
|
{!selectedRegistrySession ? (
|
|
869
857
|
<BrowserUnselectedPanel
|
|
870
|
-
unavailableBrowser={unavailableBrowser}
|
|
871
858
|
peerCount={liveSessions.length}
|
|
872
859
|
creating={creating}
|
|
873
860
|
onCreate={() => createBrowser()}
|
|
@@ -1199,7 +1186,6 @@ function BrowserToolbar(props: {
|
|
|
1199
1186
|
}
|
|
1200
1187
|
|
|
1201
1188
|
function BrowserUnselectedPanel(props: {
|
|
1202
|
-
unavailableBrowser: BrowserSession | undefined;
|
|
1203
1189
|
peerCount: number;
|
|
1204
1190
|
creating: boolean;
|
|
1205
1191
|
onCreate: () => void;
|
|
@@ -1210,11 +1196,7 @@ function BrowserUnselectedPanel(props: {
|
|
|
1210
1196
|
<span className="mx-auto grid size-10 place-items-center rounded-og-md border border-og-border bg-og-surface-1 text-og-fg-muted">
|
|
1211
1197
|
<Globe2Icon className="size-4.5" />
|
|
1212
1198
|
</span>
|
|
1213
|
-
|
|
1214
|
-
<BrowserUnavailableNotice session={props.unavailableBrowser} />
|
|
1215
|
-
) : (
|
|
1216
|
-
<p className="mt-3 text-og-menu font-medium text-og-fg">No browser for this agent</p>
|
|
1217
|
-
)}
|
|
1199
|
+
<p className="mt-3 text-og-menu font-medium text-og-fg">No browser for this agent</p>
|
|
1218
1200
|
<p className="mt-1 text-og-control leading-5 text-og-fg-muted">
|
|
1219
1201
|
{props.peerCount === 1
|
|
1220
1202
|
? "One workspace browser is available from the browser menu."
|
|
@@ -1234,25 +1216,6 @@ function BrowserUnselectedPanel(props: {
|
|
|
1234
1216
|
);
|
|
1235
1217
|
}
|
|
1236
1218
|
|
|
1237
|
-
function BrowserUnavailableNotice({ session }: { session: BrowserSession }) {
|
|
1238
|
-
const reason =
|
|
1239
|
-
session.failureCode === "provider_deadline_rotation"
|
|
1240
|
-
? "The computer running it reached its time limit."
|
|
1241
|
-
: session.failureCode === "source_placement_changed"
|
|
1242
|
-
? "This chat moved to another computer."
|
|
1243
|
-
: session.lifecycle === "failed"
|
|
1244
|
-
? "It stopped unexpectedly."
|
|
1245
|
-
: "The connection to it was lost.";
|
|
1246
|
-
return (
|
|
1247
|
-
<div role="status">
|
|
1248
|
-
<p className="mt-3 text-og-menu font-medium text-og-fg">Browser unavailable</p>
|
|
1249
|
-
<p className="mt-1 break-words text-og-control leading-5 text-og-fg-muted">
|
|
1250
|
-
{session.name}. {reason} Open a new browser to continue.
|
|
1251
|
-
</p>
|
|
1252
|
-
</div>
|
|
1253
|
-
);
|
|
1254
|
-
}
|
|
1255
|
-
|
|
1256
1219
|
function BrowserSessionGroup(props: {
|
|
1257
1220
|
label: string;
|
|
1258
1221
|
sessions: BrowserSession[];
|
|
@@ -1756,8 +1719,7 @@ function BrowserProfileMenu(props: {
|
|
|
1756
1719
|
) : null}
|
|
1757
1720
|
{canSave ? (
|
|
1758
1721
|
<p className="mt-2 text-[10px] leading-4 text-og-fg-subtle">
|
|
1759
|
-
Saving restarts this browser.
|
|
1760
|
-
entries may be lost. Other open browsers are unchanged.
|
|
1722
|
+
Saving briefly restarts this browser. Other open browsers are unchanged.
|
|
1761
1723
|
</p>
|
|
1762
1724
|
) : null}
|
|
1763
1725
|
</div>
|
|
@@ -2778,14 +2740,13 @@ function BrowserDiagnosticsDrawer(props: {
|
|
|
2778
2740
|
id="browser-page-title"
|
|
2779
2741
|
className="text-[10px] font-semibold uppercase tracking-[0.14em] text-og-fg-subtle"
|
|
2780
2742
|
>
|
|
2781
|
-
|
|
2743
|
+
Current page
|
|
2782
2744
|
</h3>
|
|
2783
|
-
<p className="mt-1 text-og-xs text-og-fg-subtle">Includes earlier pages in this tab.</p>
|
|
2784
2745
|
<dl className="mt-2 grid grid-cols-2 gap-2">
|
|
2785
|
-
<DiagnosticCount label="Console errors" value={diagnostics?.consoleErrorCount} />
|
|
2786
|
-
<DiagnosticCount label="Page errors" value={diagnostics?.pageErrorCount} />
|
|
2787
|
-
<DiagnosticCount label="Failed requests" value={diagnostics?.failedRequestCount} />
|
|
2788
|
-
<DiagnosticCount label="Downloads" value={diagnostics?.downloadCount} />
|
|
2746
|
+
<DiagnosticCount label="Console errors" value={diagnostics?.consoleErrorCount ?? 0} />
|
|
2747
|
+
<DiagnosticCount label="Page errors" value={diagnostics?.pageErrorCount ?? 0} />
|
|
2748
|
+
<DiagnosticCount label="Failed requests" value={diagnostics?.failedRequestCount ?? 0} />
|
|
2749
|
+
<DiagnosticCount label="Downloads" value={diagnostics?.downloadCount ?? 0} />
|
|
2789
2750
|
</dl>
|
|
2790
2751
|
{session?.failureCode ? (
|
|
2791
2752
|
<p className="mt-2 rounded-og-sm border border-og-status-error/30 bg-og-status-error/5 px-2.5 py-2 text-og-xs text-og-danger">
|
|
@@ -3083,7 +3044,7 @@ function DiagnosticFact(props: { label: string; value: string }) {
|
|
|
3083
3044
|
);
|
|
3084
3045
|
}
|
|
3085
3046
|
|
|
3086
|
-
function DiagnosticCount(props: { label: string; value: number
|
|
3047
|
+
function DiagnosticCount(props: { label: string; value: number }) {
|
|
3087
3048
|
return (
|
|
3088
3049
|
<div className="rounded-og-sm border border-og-border bg-og-bg px-2.5 py-2">
|
|
3089
3050
|
<dt className="text-[10px] text-og-fg-subtle">{props.label}</dt>
|
|
@@ -3093,7 +3054,7 @@ function DiagnosticCount(props: { label: string; value: number | undefined }) {
|
|
|
3093
3054
|
props.value ? "text-og-fg" : "text-og-fg-muted",
|
|
3094
3055
|
)}
|
|
3095
3056
|
>
|
|
3096
|
-
{props.value
|
|
3057
|
+
{props.value}
|
|
3097
3058
|
</dd>
|
|
3098
3059
|
</div>
|
|
3099
3060
|
);
|
|
@@ -289,19 +289,13 @@ export function ComputerViewer({
|
|
|
289
289
|
: null;
|
|
290
290
|
const rfbStream =
|
|
291
291
|
frames.attachment?.stream.kind === "direct_rfb" ? frames.attachment.stream : null;
|
|
292
|
-
const machineLocked = selectedRegistrySession?.failureCode === "machine_locked";
|
|
293
|
-
// RFB has one combined input switch; partial native input stays view-only.
|
|
294
|
-
const rfbInputEnabled =
|
|
295
|
-
!machineLocked &&
|
|
296
|
-
computer.session?.capabilities?.pointerInput === true &&
|
|
297
|
-
computer.session?.capabilities?.keyboardInput === true;
|
|
298
292
|
const rfbCapability = useMemo<DesktopStreamCapability | null>(() => {
|
|
299
293
|
if (!rfbStream || !frames.attachment) return null;
|
|
300
294
|
const bounds = computer.selectedTarget?.bounds;
|
|
301
295
|
return {
|
|
302
296
|
transport: "vnc-ws",
|
|
303
297
|
client: "novnc",
|
|
304
|
-
mode:
|
|
298
|
+
mode: "interactive",
|
|
305
299
|
url: rfbStream.url,
|
|
306
300
|
token: null,
|
|
307
301
|
expiresAt: frames.attachment.expiresAt,
|
|
@@ -313,7 +307,8 @@ export function ComputerViewer({
|
|
|
313
307
|
sharedSessionIds: [],
|
|
314
308
|
reason: null,
|
|
315
309
|
};
|
|
316
|
-
}, [computer.selectedTarget?.bounds, frames.attachment,
|
|
310
|
+
}, [computer.selectedTarget?.bounds, frames.attachment, rfbStream]);
|
|
311
|
+
const machineLocked = selectedRegistrySession?.failureCode === "machine_locked";
|
|
317
312
|
const currentIds = useMemo(() => new Set(relevant.map((session) => session.id)), [relevant]);
|
|
318
313
|
|
|
319
314
|
useEffect(() => {
|
|
@@ -457,8 +452,7 @@ export function ComputerViewer({
|
|
|
457
452
|
|
|
458
453
|
const copyFromRfb = useCallback(
|
|
459
454
|
(event: ClipboardEvent<HTMLDivElement>) => {
|
|
460
|
-
if (!
|
|
461
|
-
return;
|
|
455
|
+
if (!rfbStream || computer.session?.capabilities?.clipboard !== true) return;
|
|
462
456
|
event.preventDefault();
|
|
463
457
|
event.stopPropagation();
|
|
464
458
|
void perform({ type: "clipboard", operation: "copy" }, null)
|
|
@@ -470,13 +464,12 @@ export function ComputerViewer({
|
|
|
470
464
|
})
|
|
471
465
|
.catch((cause) => notifyError(cause, "Could not copy from the desktop."));
|
|
472
466
|
},
|
|
473
|
-
[computer, notifyError, perform,
|
|
467
|
+
[computer, notifyError, perform, rfbStream],
|
|
474
468
|
);
|
|
475
469
|
|
|
476
470
|
const pasteIntoRfb = useCallback(
|
|
477
471
|
(text: string): boolean => {
|
|
478
|
-
if (!
|
|
479
|
-
return false;
|
|
472
|
+
if (!rfbStream || computer.session?.capabilities?.clipboard !== true) return false;
|
|
480
473
|
// Keep paste on the canonical ComputerSession action path. RFB
|
|
481
474
|
// ClientCutText synchronization varies by server and can acknowledge a
|
|
482
475
|
// local paste without ever updating the remote graphical seat. These two
|
|
@@ -491,7 +484,7 @@ export function ComputerViewer({
|
|
|
491
484
|
})().catch((cause) => notifyError(cause, "Could not paste into the desktop."));
|
|
492
485
|
return true;
|
|
493
486
|
},
|
|
494
|
-
[computer, notifyError, perform,
|
|
487
|
+
[computer, notifyError, perform, rfbStream],
|
|
495
488
|
);
|
|
496
489
|
|
|
497
490
|
const hideGenericCreate = suppressGenericCreate && liveRelevant.length === 0;
|
|
@@ -630,18 +623,13 @@ export function ComputerViewer({
|
|
|
630
623
|
<div className="relative min-h-0 flex-1 bg-black" onCopyCapture={copyFromRfb}>
|
|
631
624
|
<DesktopViewer
|
|
632
625
|
capability={rfbCapability}
|
|
633
|
-
interactive
|
|
626
|
+
interactive
|
|
634
627
|
showControlToggle={false}
|
|
635
628
|
webSocketProtocols={rfbStream.protocols}
|
|
636
629
|
onPasteText={pasteIntoRfb}
|
|
637
630
|
targetPlatform={computer.session?.platform ?? null}
|
|
638
631
|
className="h-full"
|
|
639
632
|
/>
|
|
640
|
-
{!rfbInputEnabled ? (
|
|
641
|
-
<div className="pointer-events-none absolute bottom-3 left-1/2 -translate-x-1/2 rounded-full border border-white/10 bg-black/70 px-3 py-1 text-[11px] text-white/80 backdrop-blur">
|
|
642
|
-
View only · direct input unavailable
|
|
643
|
-
</div>
|
|
644
|
-
) : null}
|
|
645
633
|
</div>
|
|
646
634
|
) : (
|
|
647
635
|
<ComputerViewport
|
|
@@ -660,8 +648,6 @@ export function ComputerViewer({
|
|
|
660
648
|
mutating={computer.mutating}
|
|
661
649
|
backgroundActions={computer.session?.capabilities?.backgroundActions === true}
|
|
662
650
|
clipboardEnabled={computer.session?.capabilities?.clipboard === true}
|
|
663
|
-
pointerInput={computer.session?.capabilities?.pointerInput === true}
|
|
664
|
-
keyboardInput={computer.session?.capabilities?.keyboardInput === true}
|
|
665
651
|
onAction={perform}
|
|
666
652
|
onReadClipboard={computer.readClipboard}
|
|
667
653
|
onReconnect={
|
|
@@ -1025,8 +1011,6 @@ function ComputerViewport(props: {
|
|
|
1025
1011
|
mutating: boolean;
|
|
1026
1012
|
backgroundActions: boolean;
|
|
1027
1013
|
clipboardEnabled: boolean;
|
|
1028
|
-
pointerInput: boolean;
|
|
1029
|
-
keyboardInput: boolean;
|
|
1030
1014
|
onAction: (action: ComputerAction, frame: ComputerFrame | null) => Promise<void>;
|
|
1031
1015
|
onReadClipboard: () => Promise<ComputerClipboard>;
|
|
1032
1016
|
onReconnect: () => void;
|
|
@@ -1086,9 +1070,6 @@ function ComputerViewport(props: {
|
|
|
1086
1070
|
if (inputRef.current) inputRef.current.value = "";
|
|
1087
1071
|
}, []);
|
|
1088
1072
|
|
|
1089
|
-
const pointerInputEnabled = rawInputEnabled && props.pointerInput;
|
|
1090
|
-
const keyboardInputEnabled = rawInputEnabled && props.keyboardInput;
|
|
1091
|
-
|
|
1092
1073
|
const paintQueuedFrames = useCallback(() => {
|
|
1093
1074
|
if (decodingFrameRef.current) return;
|
|
1094
1075
|
decodingFrameRef.current = true;
|
|
@@ -1178,11 +1159,11 @@ function ComputerViewport(props: {
|
|
|
1178
1159
|
}, [clearBufferedInput, paintQueuedFrames, props.frame]);
|
|
1179
1160
|
|
|
1180
1161
|
useLayoutEffect(() => {
|
|
1181
|
-
if (!rawInputEnabled
|
|
1162
|
+
if (!rawInputEnabled) {
|
|
1182
1163
|
actionQueueEpochRef.current += 1;
|
|
1183
1164
|
clearBufferedInput();
|
|
1184
1165
|
}
|
|
1185
|
-
}, [clearBufferedInput,
|
|
1166
|
+
}, [clearBufferedInput, rawInputEnabled]);
|
|
1186
1167
|
|
|
1187
1168
|
const enqueue = useCallback(
|
|
1188
1169
|
(
|
|
@@ -1267,8 +1248,6 @@ function ComputerViewport(props: {
|
|
|
1267
1248
|
if (!frame || props.mutating || !rawInputEnabled || event.button !== 0) return;
|
|
1268
1249
|
// Preserve the keyboard sink's focus through the canvas pointer default action.
|
|
1269
1250
|
event.preventDefault();
|
|
1270
|
-
if (keyboardInputEnabled) inputRef.current?.focus({ preventScroll: true });
|
|
1271
|
-
if (!pointerInputEnabled) return;
|
|
1272
1251
|
flushPendingWheel();
|
|
1273
1252
|
flushPendingText();
|
|
1274
1253
|
pointerStartRef.current = {
|
|
@@ -1278,10 +1257,11 @@ function ComputerViewport(props: {
|
|
|
1278
1257
|
frame,
|
|
1279
1258
|
};
|
|
1280
1259
|
event.currentTarget.setPointerCapture?.(event.pointerId);
|
|
1260
|
+
inputRef.current?.focus({ preventScroll: true });
|
|
1281
1261
|
};
|
|
1282
1262
|
|
|
1283
1263
|
const pointerUp = (event: PointerEvent<HTMLCanvasElement>) => {
|
|
1284
|
-
if (!
|
|
1264
|
+
if (!rawInputEnabled) return;
|
|
1285
1265
|
const start = pointerStartRef.current;
|
|
1286
1266
|
pointerStartRef.current = null;
|
|
1287
1267
|
if (!start || start.pointerId !== event.pointerId) return;
|
|
@@ -1346,7 +1326,7 @@ function ComputerViewport(props: {
|
|
|
1346
1326
|
|
|
1347
1327
|
const contextMenu = (event: MouseEvent<HTMLCanvasElement>) => {
|
|
1348
1328
|
event.preventDefault();
|
|
1349
|
-
if (!
|
|
1329
|
+
if (!rawInputEnabled) return;
|
|
1350
1330
|
const frame = paintedFrameRef.current;
|
|
1351
1331
|
if (!frame) return;
|
|
1352
1332
|
flushPendingWheel();
|
|
@@ -1369,7 +1349,7 @@ function ComputerViewport(props: {
|
|
|
1369
1349
|
};
|
|
1370
1350
|
|
|
1371
1351
|
const wheel = (event: WheelEvent<HTMLCanvasElement>) => {
|
|
1372
|
-
if (!
|
|
1352
|
+
if (!rawInputEnabled) return;
|
|
1373
1353
|
const frame = paintedFrameRef.current;
|
|
1374
1354
|
if (!frame) return;
|
|
1375
1355
|
const at = point(frame, event.clientX, event.clientY);
|
|
@@ -1397,7 +1377,7 @@ function ComputerViewport(props: {
|
|
|
1397
1377
|
};
|
|
1398
1378
|
|
|
1399
1379
|
const keyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {
|
|
1400
|
-
if (!
|
|
1380
|
+
if (!rawInputEnabled) return;
|
|
1401
1381
|
flushPendingWheel();
|
|
1402
1382
|
const command = event.metaKey || event.ctrlKey;
|
|
1403
1383
|
if (
|
|
@@ -1418,7 +1398,7 @@ function ComputerViewport(props: {
|
|
|
1418
1398
|
};
|
|
1419
1399
|
|
|
1420
1400
|
const copy = (event: ClipboardEvent<HTMLTextAreaElement>) => {
|
|
1421
|
-
if (!props.clipboardEnabled || !
|
|
1401
|
+
if (!props.clipboardEnabled || !rawInputEnabled) return;
|
|
1422
1402
|
event.preventDefault();
|
|
1423
1403
|
flushPendingWheel();
|
|
1424
1404
|
flushPendingText();
|
|
@@ -1435,7 +1415,7 @@ function ComputerViewport(props: {
|
|
|
1435
1415
|
};
|
|
1436
1416
|
|
|
1437
1417
|
const paste = (event: ClipboardEvent<HTMLTextAreaElement>) => {
|
|
1438
|
-
if (!props.clipboardEnabled || !
|
|
1418
|
+
if (!props.clipboardEnabled || !rawInputEnabled) return;
|
|
1439
1419
|
event.preventDefault();
|
|
1440
1420
|
flushPendingWheel();
|
|
1441
1421
|
flushPendingText();
|
|
@@ -1452,7 +1432,7 @@ function ComputerViewport(props: {
|
|
|
1452
1432
|
};
|
|
1453
1433
|
|
|
1454
1434
|
const input = (value: string) => {
|
|
1455
|
-
if (!value || !
|
|
1435
|
+
if (!value || !rawInputEnabled) return;
|
|
1456
1436
|
flushPendingWheel();
|
|
1457
1437
|
flushPendingClick();
|
|
1458
1438
|
const pending = pendingTextRef.current;
|
|
@@ -1482,7 +1462,7 @@ function ComputerViewport(props: {
|
|
|
1482
1462
|
className={cn(
|
|
1483
1463
|
"absolute inset-0 m-auto max-h-full max-w-full touch-none focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-og-accent",
|
|
1484
1464
|
!showCanvas && "invisible",
|
|
1485
|
-
!
|
|
1465
|
+
!rawInputEnabled && "cursor-default",
|
|
1486
1466
|
)}
|
|
1487
1467
|
onPointerDown={pointerDown}
|
|
1488
1468
|
onPointerUp={pointerUp}
|
|
@@ -1505,7 +1485,7 @@ function ComputerViewport(props: {
|
|
|
1505
1485
|
autoCapitalize="off"
|
|
1506
1486
|
autoCorrect="off"
|
|
1507
1487
|
spellCheck={false}
|
|
1508
|
-
disabled={!
|
|
1488
|
+
disabled={!rawInputEnabled}
|
|
1509
1489
|
/>
|
|
1510
1490
|
{!showCanvas ? (
|
|
1511
1491
|
<ComputerViewportFallback
|
|
@@ -1522,18 +1502,10 @@ function ComputerViewport(props: {
|
|
|
1522
1502
|
<LoaderCircleIcon className="size-3 animate-spin" /> Acting
|
|
1523
1503
|
</div>
|
|
1524
1504
|
) : null}
|
|
1525
|
-
{showCanvas &&
|
|
1505
|
+
{showCanvas && !rawInputEnabled ? (
|
|
1526
1506
|
<div className="absolute bottom-3 left-1/2 flex -translate-x-1/2 items-center gap-2 rounded-full border border-white/10 bg-black/70 py-1 pl-3 pr-1 text-[11px] text-white/80 backdrop-blur">
|
|
1527
|
-
<span>
|
|
1528
|
-
|
|
1529
|
-
? "Background view · use native controls"
|
|
1530
|
-
: !props.pointerInput && !props.keyboardInput
|
|
1531
|
-
? "View only · mouse and keyboard unavailable"
|
|
1532
|
-
: props.keyboardInput
|
|
1533
|
-
? "Keyboard only · mouse unavailable"
|
|
1534
|
-
: "Mouse only · keyboard unavailable"}
|
|
1535
|
-
</span>
|
|
1536
|
-
{!rawInputEnabled && props.target && (props.pointerInput || props.keyboardInput) ? (
|
|
1507
|
+
<span>Background view · use native controls</span>
|
|
1508
|
+
{props.target ? (
|
|
1537
1509
|
<button
|
|
1538
1510
|
type="button"
|
|
1539
1511
|
disabled={props.mutating}
|