@opengeni/react 0.6.1 → 0.6.3
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/{chunk-DEW2ZNF2.js → chunk-5C7RGAWA.js} +70 -37
- package/dist/chunk-5C7RGAWA.js.map +1 -0
- package/dist/index.d.ts +29 -5
- package/dist/index.js +1061 -618
- package/dist/index.js.map +1 -1
- package/dist/{machines-BD6h9P_s.d.ts → machines-Bv9tG7qZ.d.ts} +1 -1
- package/dist/machines.d.ts +1 -1
- package/dist/machines.js +1 -1
- package/package.json +2 -2
- package/src/components/chat-composer.tsx +127 -60
- package/src/components/code-editor.tsx +15 -15
- package/src/components/desktop-viewer.tsx +40 -36
- package/src/components/diff-view.tsx +22 -22
- package/src/components/enrollment-consent.tsx +13 -13
- package/src/components/file-browser.tsx +74 -67
- package/src/components/fleet-tile.tsx +3 -3
- package/src/components/machine-card.tsx +6 -6
- package/src/components/machine-status-pill.tsx +3 -3
- package/src/components/machines-dashboard.tsx +28 -14
- package/src/components/markdown.tsx +6 -6
- package/src/components/message-timeline.tsx +75 -4
- package/src/components/pierre-diff.tsx +9 -10
- package/src/components/pierre-file.tsx +8 -8
- package/src/components/sandbox-files.tsx +37 -40
- package/src/components/sandbox-terminal.tsx +9 -11
- package/src/components/session-status.tsx +2 -2
- package/src/components/workspace-dock.tsx +153 -49
- package/src/hooks/use-file-attachments.ts +45 -15
- package/src/index.ts +2 -2
- package/src/lib/format.ts +32 -0
- package/src/lib/xterm-theme.ts +8 -11
- package/src/timeline/activity-rail.tsx +1 -1
- package/src/timeline/parsers.ts +104 -0
- package/src/timeline/projection.ts +135 -3
- package/src/timeline/screenshot-lightbox.tsx +1 -1
- package/src/timeline/shared.tsx +4 -1
- package/src/timeline/tool-diff.tsx +1 -1
- package/src/timeline/tool-renderers.tsx +46 -7
- package/src/timeline/turn-summary.tsx +21 -3
- package/src/timeline/types.ts +2 -0
- package/styles/tokens.css +8 -0
- package/dist/chunk-DEW2ZNF2.js.map +0 -1
|
@@ -84,6 +84,10 @@ type DesktopUiState =
|
|
|
84
84
|
| "error" // RFB error / securityfailure after a connect.
|
|
85
85
|
| "connected"; // live framebuffer painting.
|
|
86
86
|
|
|
87
|
+
// Media-inspection exception: the framebuffer sits on true black so screenshots
|
|
88
|
+
// and desktop pixels are not tinted by the product chrome palette.
|
|
89
|
+
const DESKTOP_MEDIA_BACKGROUND = "#000";
|
|
90
|
+
|
|
87
91
|
/** Reasons that are genuinely-unavailable (never warmable from the viewer). A
|
|
88
92
|
* `lease_cold` is deliberately EXCLUDED — that's the warmable cold state. */
|
|
89
93
|
function isHardUnavailable(reason: CapabilityUnavailableReason | null): boolean {
|
|
@@ -369,11 +373,11 @@ export function DesktopViewer({
|
|
|
369
373
|
return (
|
|
370
374
|
<div
|
|
371
375
|
className={cn(
|
|
372
|
-
"relative h-full w-full overflow-hidden
|
|
373
|
-
inControl &&
|
|
374
|
-
"ring-2 ring-inset ring-[color:var(--og-color-accent,var(--color-brand,#3b82f6))]",
|
|
376
|
+
"relative h-full w-full overflow-hidden",
|
|
377
|
+
inControl && "ring-2 ring-inset ring-og-accent",
|
|
375
378
|
className,
|
|
376
379
|
)}
|
|
380
|
+
style={{ backgroundColor: DESKTOP_MEDIA_BACKGROUND }}
|
|
377
381
|
data-opengeni-desktop
|
|
378
382
|
data-state={stream.state}
|
|
379
383
|
data-ui-state={uiState}
|
|
@@ -399,15 +403,15 @@ export function DesktopViewer({
|
|
|
399
403
|
`connecting` UI-state (every other non-connected state has an explicit
|
|
400
404
|
overlay). A spinner + transitional copy makes it feel live. */}
|
|
401
405
|
{uiState === "connecting" && (
|
|
402
|
-
<div className="pointer-events-none absolute inset-0 flex flex-col items-center justify-center gap-3 text-
|
|
406
|
+
<div className="pointer-events-none absolute inset-0 flex flex-col items-center justify-center gap-3 text-og-fg-subtle">
|
|
403
407
|
<span className="relative flex items-center justify-center">
|
|
404
408
|
<MonitorIcon className="size-8 opacity-30" strokeWidth={1.5} />
|
|
405
409
|
<LoaderCircleIcon
|
|
406
|
-
className="absolute size-12 animate-og-spin text-
|
|
410
|
+
className="absolute size-12 animate-og-spin text-og-accent opacity-70"
|
|
407
411
|
strokeWidth={1.25}
|
|
408
412
|
/>
|
|
409
413
|
</span>
|
|
410
|
-
<span className="text-
|
|
414
|
+
<span className="text-og-sm">Connecting to the desktop…</span>
|
|
411
415
|
</div>
|
|
412
416
|
)}
|
|
413
417
|
|
|
@@ -438,7 +442,7 @@ export function DesktopViewer({
|
|
|
438
442
|
!serverAllowsControl
|
|
439
443
|
? capability?.client === "frames"
|
|
440
444
|
? "View-only — live control isn't available for this machine yet."
|
|
441
|
-
: "This deployment streams the desktop read-only"
|
|
445
|
+
: "This deployment streams the desktop read-only."
|
|
442
446
|
: undefined
|
|
443
447
|
}
|
|
444
448
|
onTakeControl={() => setTakeControl(true)}
|
|
@@ -481,36 +485,36 @@ function TakeControlCallToAction({
|
|
|
481
485
|
title={disabled ? disabledReason : "Take control of the desktop"}
|
|
482
486
|
onClick={onTakeControl}
|
|
483
487
|
className={cn(
|
|
484
|
-
"group pointer-events-auto flex items-center gap-3 rounded-
|
|
485
|
-
"border-
|
|
486
|
-
"bg-
|
|
487
|
-
"shadow-
|
|
488
|
+
"group pointer-events-auto flex items-center gap-3 rounded-og-lg border px-5 py-3",
|
|
489
|
+
"border-og-border",
|
|
490
|
+
"bg-og-bg/85 backdrop-blur-md",
|
|
491
|
+
"shadow-og-lg",
|
|
488
492
|
"outline-none transition-all duration-150 ease-out",
|
|
489
|
-
"focus-visible:ring-2 focus-visible:ring-
|
|
493
|
+
"focus-visible:ring-2 focus-visible:ring-og-accent focus-visible:ring-offset-2 focus-visible:ring-offset-og-bg",
|
|
490
494
|
disabled
|
|
491
495
|
? "cursor-not-allowed opacity-60"
|
|
492
496
|
: cn(
|
|
493
497
|
"cursor-pointer opacity-90 hover:-translate-y-0.5 hover:opacity-100",
|
|
494
|
-
"hover:border-
|
|
495
|
-
"hover:bg-
|
|
498
|
+
"hover:border-og-accent",
|
|
499
|
+
"hover:bg-og-accent/10",
|
|
496
500
|
),
|
|
497
501
|
)}
|
|
498
502
|
>
|
|
499
503
|
<span
|
|
500
504
|
className={cn(
|
|
501
505
|
"flex size-9 shrink-0 items-center justify-center rounded-full transition-colors",
|
|
502
|
-
"bg-
|
|
503
|
-
"text-
|
|
506
|
+
"bg-og-accent",
|
|
507
|
+
"text-og-accent-fg",
|
|
504
508
|
disabled ? "" : "group-hover:scale-105",
|
|
505
509
|
)}
|
|
506
510
|
>
|
|
507
511
|
<MousePointerClickIcon className="size-5" strokeWidth={2} />
|
|
508
512
|
</span>
|
|
509
513
|
<span className="flex flex-col items-start leading-tight">
|
|
510
|
-
<span className="text-
|
|
514
|
+
<span className="text-og-base font-semibold text-og-fg">
|
|
511
515
|
Take control
|
|
512
516
|
</span>
|
|
513
|
-
<span className="text-
|
|
517
|
+
<span className="text-og-xs text-og-fg-subtle">
|
|
514
518
|
{disabled && disabledReason ? disabledReason : "Drive the mouse & keyboard"}
|
|
515
519
|
</span>
|
|
516
520
|
</span>
|
|
@@ -530,15 +534,15 @@ function TakeControlCallToAction({
|
|
|
530
534
|
function InControlBar({ shared, onRelease }: { shared: boolean; onRelease: () => void }) {
|
|
531
535
|
return (
|
|
532
536
|
<div className="pointer-events-none absolute inset-x-0 top-0 flex items-center justify-between gap-2 p-2">
|
|
533
|
-
<span className="pointer-events-auto inline-flex items-center gap-2 rounded-
|
|
537
|
+
<span className="pointer-events-auto inline-flex items-center gap-2 rounded-og-sm bg-og-accent px-2.5 py-1 text-og-xs font-medium text-og-accent-fg shadow-og-md">
|
|
534
538
|
<span className="size-1.5 animate-pulse rounded-full bg-current" aria-hidden />
|
|
535
539
|
You're in control
|
|
536
540
|
<span className="opacity-75">· click Return control (or Ctrl+Alt+Shift)</span>
|
|
537
541
|
</span>
|
|
538
542
|
<div className="pointer-events-auto flex items-center gap-1.5">
|
|
539
543
|
{shared && (
|
|
540
|
-
<span className="rounded-
|
|
541
|
-
Shared
|
|
544
|
+
<span className="rounded-og-sm bg-og-status-failed/85 px-2 py-0.5 text-og-xs text-og-accent-fg">
|
|
545
|
+
Shared sandbox — others are watching
|
|
542
546
|
</span>
|
|
543
547
|
)}
|
|
544
548
|
<button
|
|
@@ -546,9 +550,9 @@ function InControlBar({ shared, onRelease }: { shared: boolean; onRelease: () =>
|
|
|
546
550
|
onClick={onRelease}
|
|
547
551
|
title="Return control (or press Ctrl+Alt+Shift)"
|
|
548
552
|
className={cn(
|
|
549
|
-
"inline-flex items-center gap-1.5 rounded-
|
|
550
|
-
"border-
|
|
551
|
-
"outline-none hover:bg-
|
|
553
|
+
"inline-flex items-center gap-1.5 rounded-og-sm border px-2.5 py-1 text-og-xs font-semibold shadow-og-md transition-colors",
|
|
554
|
+
"border-og-accent bg-og-bg/90 text-og-fg backdrop-blur-sm",
|
|
555
|
+
"outline-none hover:bg-og-accent hover:text-og-accent-fg focus-visible:ring-2 focus-visible:ring-og-accent",
|
|
552
556
|
)}
|
|
553
557
|
>
|
|
554
558
|
<MonitorIcon className="size-3.5" strokeWidth={2} aria-hidden />
|
|
@@ -568,7 +572,7 @@ function unavailableCopy(reason: CapabilityUnavailableReason | null): string {
|
|
|
568
572
|
case "os_unsupported":
|
|
569
573
|
return "The sandbox OS does not support a desktop stream.";
|
|
570
574
|
case "not_provisioned":
|
|
571
|
-
return "
|
|
575
|
+
return "This sandbox doesn't have a desktop yet.";
|
|
572
576
|
case "disabled_by_policy":
|
|
573
577
|
return "Desktop streaming is disabled on this deployment.";
|
|
574
578
|
case "lease_cold":
|
|
@@ -589,14 +593,14 @@ function unavailableCopy(reason: CapabilityUnavailableReason | null): string {
|
|
|
589
593
|
*/
|
|
590
594
|
function WarmingNotice({ onRetry }: { onRetry?: (() => void) | undefined }) {
|
|
591
595
|
return (
|
|
592
|
-
<div className="flex max-w-sm flex-col items-center gap-3 rounded-lg border border-
|
|
596
|
+
<div className="flex max-w-sm flex-col items-center gap-3 rounded-og-lg border border-og-border bg-og-bg/90 p-5 text-center text-og-base text-og-fg backdrop-blur-sm">
|
|
593
597
|
<LoaderCircleIcon
|
|
594
|
-
className="size-7 animate-og-spin text-
|
|
598
|
+
className="size-7 animate-og-spin text-og-accent"
|
|
595
599
|
strokeWidth={1.5}
|
|
596
600
|
/>
|
|
597
601
|
<div className="space-y-1">
|
|
598
602
|
<div className="font-medium">Warming the sandbox…</div>
|
|
599
|
-
<p className="text-
|
|
603
|
+
<p className="text-og-sm text-og-fg-subtle">
|
|
600
604
|
Spinning up the desktop — this takes a few seconds.
|
|
601
605
|
</p>
|
|
602
606
|
</div>
|
|
@@ -604,7 +608,7 @@ function WarmingNotice({ onRetry }: { onRetry?: (() => void) | undefined }) {
|
|
|
604
608
|
<button
|
|
605
609
|
type="button"
|
|
606
610
|
onClick={onRetry}
|
|
607
|
-
className="rounded border border-
|
|
611
|
+
className="rounded-og-sm border border-og-border px-3 py-1.5 text-og-sm text-og-fg-muted transition-colors hover:text-og-fg pointer-coarse:min-h-10"
|
|
608
612
|
>
|
|
609
613
|
Taking too long? Retry
|
|
610
614
|
</button>
|
|
@@ -615,19 +619,19 @@ function WarmingNotice({ onRetry }: { onRetry?: (() => void) | undefined }) {
|
|
|
615
619
|
|
|
616
620
|
function DefaultConsentGate({ shared, onAccept }: { shared: boolean; onAccept: () => void }) {
|
|
617
621
|
return (
|
|
618
|
-
<div className="max-w-sm rounded-lg border border-
|
|
622
|
+
<div className="max-w-sm rounded-og-lg border border-og-border bg-og-bg p-4 text-center text-og-base text-og-fg">
|
|
619
623
|
<div className="mb-1 font-medium">Watch the live desktop?</div>
|
|
620
|
-
<p className="mb-3 text-
|
|
624
|
+
<p className="mb-3 text-og-sm text-og-fg-subtle">
|
|
621
625
|
The desktop pixel stream is <strong>un-redacted</strong> — it can show secrets the agent prints
|
|
622
626
|
on screen.
|
|
623
627
|
{shared
|
|
624
|
-
? " This
|
|
628
|
+
? " This sandbox is shared: you'll also see other sessions' agents on the same screen."
|
|
625
629
|
: ""}
|
|
626
630
|
</p>
|
|
627
631
|
<button
|
|
628
632
|
type="button"
|
|
629
633
|
onClick={onAccept}
|
|
630
|
-
className="rounded bg-
|
|
634
|
+
className="rounded-og-sm bg-og-accent px-3 py-1.5 text-og-sm font-medium text-og-accent-fg pointer-coarse:min-h-10"
|
|
631
635
|
>
|
|
632
636
|
I understand — show the desktop
|
|
633
637
|
</button>
|
|
@@ -637,17 +641,17 @@ function DefaultConsentGate({ shared, onAccept }: { shared: boolean; onAccept: (
|
|
|
637
641
|
|
|
638
642
|
function defaultNotice(title: string, body: string, onRetry?: () => void): ReactNode {
|
|
639
643
|
return (
|
|
640
|
-
<div className="max-w-sm rounded-lg border border-
|
|
644
|
+
<div className="max-w-sm rounded-og-lg border border-og-border bg-og-bg p-4 text-center text-og-base text-og-fg">
|
|
641
645
|
<div className="mb-1 flex items-center justify-center gap-1.5 font-medium">
|
|
642
646
|
{onRetry && <WifiOffIcon className="size-4 opacity-70" strokeWidth={1.75} />}
|
|
643
647
|
{title}
|
|
644
648
|
</div>
|
|
645
|
-
<p className="text-
|
|
649
|
+
<p className="text-og-sm text-og-fg-subtle">{body}</p>
|
|
646
650
|
{onRetry && (
|
|
647
651
|
<button
|
|
648
652
|
type="button"
|
|
649
653
|
onClick={onRetry}
|
|
650
|
-
className="mt-3 rounded border border-
|
|
654
|
+
className="mt-3 rounded-og-sm border border-og-border px-3 py-1.5 text-og-sm transition-colors hover:border-og-accent pointer-coarse:min-h-10"
|
|
651
655
|
>
|
|
652
656
|
Reconnect
|
|
653
657
|
</button>
|
|
@@ -60,8 +60,8 @@ export function DiffView({
|
|
|
60
60
|
|
|
61
61
|
if (diff.length === 0) {
|
|
62
62
|
return (
|
|
63
|
-
<div className={cn("p-3 text-
|
|
64
|
-
{emptyState ?? (isRepo ? "No changes
|
|
63
|
+
<div className={cn("p-3 text-og-sm text-og-fg-subtle", className)}>
|
|
64
|
+
{emptyState ?? (isRepo ? "No changes" : "No repository mounted")}
|
|
65
65
|
</div>
|
|
66
66
|
);
|
|
67
67
|
}
|
|
@@ -93,29 +93,29 @@ function FileDiffBlock({
|
|
|
93
93
|
onSelect?: (() => void) | undefined;
|
|
94
94
|
}) {
|
|
95
95
|
return (
|
|
96
|
-
<section className="mb-2 overflow-hidden rounded border border-
|
|
96
|
+
<section className="mb-2 overflow-hidden rounded-og-sm border border-og-border">
|
|
97
97
|
<header
|
|
98
98
|
className={cn(
|
|
99
|
-
"flex items-center justify-between gap-2 border-b border-
|
|
99
|
+
"flex items-center justify-between gap-2 border-b border-og-border bg-og-surface-1 px-2 py-1 text-og-sm",
|
|
100
100
|
onSelect && "cursor-pointer",
|
|
101
101
|
)}
|
|
102
102
|
onClick={onSelect}
|
|
103
103
|
>
|
|
104
|
-
<span className="truncate font-mono">
|
|
104
|
+
<span className="truncate font-og-mono">
|
|
105
105
|
{file.oldPath && file.oldPath !== file.path ? `${file.oldPath} → ${file.path}` : file.path}
|
|
106
106
|
</span>
|
|
107
107
|
<span className="flex shrink-0 items-center gap-2">
|
|
108
|
-
<span className="rounded bg-
|
|
108
|
+
<span className="rounded-og-xs bg-og-bg px-1 py-0.5 text-og-xs text-og-fg-subtle">
|
|
109
109
|
{STATUS_LABEL[file.status]}
|
|
110
110
|
</span>
|
|
111
|
-
<span className="text-
|
|
112
|
-
<span className="text-
|
|
111
|
+
<span className="text-og-status-idle">+{file.additions}</span>
|
|
112
|
+
<span className="text-og-status-failed">−{file.deletions}</span>
|
|
113
113
|
</span>
|
|
114
114
|
</header>
|
|
115
115
|
{file.isBinary ? (
|
|
116
|
-
<div className="px-2 py-3 text-
|
|
116
|
+
<div className="px-2 py-3 text-og-sm text-og-fg-subtle">Binary file not shown</div>
|
|
117
117
|
) : file.truncated ? (
|
|
118
|
-
<div className="px-2 py-3 text-
|
|
118
|
+
<div className="px-2 py-3 text-og-sm text-og-fg-subtle">Diff too large — truncated</div>
|
|
119
119
|
) : layout === "split" ? (
|
|
120
120
|
<SplitHunks file={file} theme={theme} />
|
|
121
121
|
) : (
|
|
@@ -126,8 +126,8 @@ function FileDiffBlock({
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
function lineBg(type: GitDiffLine["type"], theme: DiffTheme | undefined): string | undefined {
|
|
129
|
-
if (type === "add") return theme?.addBackground ?? "var(--color-diff-add
|
|
130
|
-
if (type === "del") return theme?.delBackground ?? "var(--color-diff-del
|
|
129
|
+
if (type === "add") return theme?.addBackground ?? "var(--og-color-diff-add-bg)";
|
|
130
|
+
if (type === "del") return theme?.delBackground ?? "var(--og-color-diff-del-bg)";
|
|
131
131
|
if (type === "meta") return undefined;
|
|
132
132
|
return theme?.contextBackground;
|
|
133
133
|
}
|
|
@@ -140,11 +140,11 @@ function marker(type: GitDiffLine["type"]): string {
|
|
|
140
140
|
|
|
141
141
|
function UnifiedHunks({ file, theme }: { file: GitFileDiff; theme: DiffTheme | undefined }) {
|
|
142
142
|
return (
|
|
143
|
-
<div className="font-mono text-
|
|
143
|
+
<div className="font-og-mono text-og-xs">
|
|
144
144
|
{file.hunks.map((hunk, hi) => (
|
|
145
145
|
<div key={`${file.path}-h${hi}`}>
|
|
146
146
|
<div
|
|
147
|
-
className="px-2 py-0.5 text-
|
|
147
|
+
className="px-2 py-0.5 text-og-accent"
|
|
148
148
|
style={{ color: theme?.metaForeground }}
|
|
149
149
|
>
|
|
150
150
|
{hunk.header}
|
|
@@ -155,13 +155,13 @@ function UnifiedHunks({ file, theme }: { file: GitFileDiff; theme: DiffTheme | u
|
|
|
155
155
|
className="flex"
|
|
156
156
|
style={{ backgroundColor: lineBg(line.type, theme) }}
|
|
157
157
|
>
|
|
158
|
-
<span className="w-10 shrink-0 select-none px-1 text-right text-
|
|
158
|
+
<span className="w-10 shrink-0 select-none px-1 text-right text-og-fg-subtle">
|
|
159
159
|
{line.oldNo ?? ""}
|
|
160
160
|
</span>
|
|
161
|
-
<span className="w-10 shrink-0 select-none px-1 text-right text-
|
|
161
|
+
<span className="w-10 shrink-0 select-none px-1 text-right text-og-fg-subtle">
|
|
162
162
|
{line.newNo ?? ""}
|
|
163
163
|
</span>
|
|
164
|
-
<span className="w-4 shrink-0 select-none text-center text-
|
|
164
|
+
<span className="w-4 shrink-0 select-none text-center text-og-fg-subtle">
|
|
165
165
|
{marker(line.type)}
|
|
166
166
|
</span>
|
|
167
167
|
<span className="whitespace-pre-wrap break-all px-1">{line.text}</span>
|
|
@@ -175,7 +175,7 @@ function UnifiedHunks({ file, theme }: { file: GitFileDiff; theme: DiffTheme | u
|
|
|
175
175
|
|
|
176
176
|
function SplitHunks({ file, theme }: { file: GitFileDiff; theme: DiffTheme | undefined }) {
|
|
177
177
|
return (
|
|
178
|
-
<div className="font-mono text-
|
|
178
|
+
<div className="font-og-mono text-og-xs">
|
|
179
179
|
{file.hunks.map((hunk, hi) => {
|
|
180
180
|
// Pair del/add lines side-by-side; context spans both columns.
|
|
181
181
|
const left: (GitDiffLine | null)[] = [];
|
|
@@ -193,7 +193,7 @@ function SplitHunks({ file, theme }: { file: GitFileDiff; theme: DiffTheme | und
|
|
|
193
193
|
const rows = Math.max(left.length, right.length);
|
|
194
194
|
return (
|
|
195
195
|
<div key={`${file.path}-h${hi}`}>
|
|
196
|
-
<div className="px-2 py-0.5 text-
|
|
196
|
+
<div className="px-2 py-0.5 text-og-accent" style={{ color: theme?.metaForeground }}>
|
|
197
197
|
{hunk.header}
|
|
198
198
|
</div>
|
|
199
199
|
{Array.from({ length: rows }).map((_, ri) => {
|
|
@@ -205,16 +205,16 @@ function SplitHunks({ file, theme }: { file: GitFileDiff; theme: DiffTheme | und
|
|
|
205
205
|
className="flex w-1/2 min-w-0"
|
|
206
206
|
style={{ backgroundColor: l ? lineBg(l.type, theme) : undefined }}
|
|
207
207
|
>
|
|
208
|
-
<span className="w-10 shrink-0 select-none px-1 text-right text-
|
|
208
|
+
<span className="w-10 shrink-0 select-none px-1 text-right text-og-fg-subtle">
|
|
209
209
|
{l?.oldNo ?? ""}
|
|
210
210
|
</span>
|
|
211
211
|
<span className="whitespace-pre-wrap break-all px-1">{l?.text ?? ""}</span>
|
|
212
212
|
</span>
|
|
213
213
|
<span
|
|
214
|
-
className="flex w-1/2 min-w-0 border-l border-
|
|
214
|
+
className="flex w-1/2 min-w-0 border-l border-og-border"
|
|
215
215
|
style={{ backgroundColor: r ? lineBg(r.type, theme) : undefined }}
|
|
216
216
|
>
|
|
217
|
-
<span className="w-10 shrink-0 select-none px-1 text-right text-
|
|
217
|
+
<span className="w-10 shrink-0 select-none px-1 text-right text-og-fg-subtle">
|
|
218
218
|
{r?.newNo ?? ""}
|
|
219
219
|
</span>
|
|
220
220
|
<span className="whitespace-pre-wrap break-all px-1">{r?.text ?? ""}</span>
|
|
@@ -43,8 +43,8 @@ function Capability({ icon, title, body }: { icon: ReactNode; title: string; bod
|
|
|
43
43
|
<li className="flex items-start gap-2.5">
|
|
44
44
|
<span className="mt-0.5 shrink-0 text-og-status-failed">{icon}</span>
|
|
45
45
|
<span className="min-w-0">
|
|
46
|
-
<span className="block text-
|
|
47
|
-
<span className="block text-
|
|
46
|
+
<span className="block text-og-base font-medium text-og-fg">{title}</span>
|
|
47
|
+
<span className="block text-og-sm text-og-fg-muted">{body}</span>
|
|
48
48
|
</span>
|
|
49
49
|
</li>
|
|
50
50
|
);
|
|
@@ -113,15 +113,15 @@ export function EnrollmentConsent({
|
|
|
113
113
|
<ShieldAlertIcon className="size-5" aria-hidden />
|
|
114
114
|
</span>
|
|
115
115
|
<div className="min-w-0">
|
|
116
|
-
<h1 className="text-
|
|
117
|
-
<p className="mt-1 text-
|
|
116
|
+
<h1 className="text-og-md font-semibold text-og-fg">Give the agent your whole machine?</h1>
|
|
117
|
+
<p className="mt-1 text-og-base text-og-fg-muted">
|
|
118
118
|
Approving lets the OpenGeni agent run on <span className="font-medium text-og-fg">{machine.machineName}</span> with
|
|
119
119
|
full access. This is your real computer — not a sandbox.
|
|
120
120
|
</p>
|
|
121
121
|
</div>
|
|
122
122
|
</div>
|
|
123
123
|
|
|
124
|
-
<div className="flex flex-wrap items-center gap-2 rounded-og-md border border-og-border bg-og-surface-2 px-3 py-2 text-
|
|
124
|
+
<div className="flex flex-wrap items-center gap-2 rounded-og-md border border-og-border bg-og-surface-2 px-3 py-2 text-og-sm">
|
|
125
125
|
<LaptopIcon className="size-4 text-og-fg-subtle" aria-hidden />
|
|
126
126
|
<span className="font-medium text-og-fg">{machine.machineName}</span>
|
|
127
127
|
<span className="font-og-mono text-og-fg-subtle">
|
|
@@ -163,21 +163,21 @@ export function EnrollmentConsent({
|
|
|
163
163
|
checked={allowScreenControl}
|
|
164
164
|
disabled={busy}
|
|
165
165
|
onChange={(e) => setAllowScreenControl(e.target.checked)}
|
|
166
|
-
className="mt-0.5 size-4 accent-
|
|
166
|
+
className="mt-0.5 size-4 accent-og-accent"
|
|
167
167
|
/>
|
|
168
168
|
<span className="min-w-0">
|
|
169
|
-
<span className="flex items-center gap-1.5 text-
|
|
169
|
+
<span className="flex items-center gap-1.5 text-og-base font-medium text-og-fg">
|
|
170
170
|
<ScreenShareIcon className="size-3.5 text-og-fg-muted" aria-hidden />
|
|
171
171
|
Also let the agent control my mouse & keyboard
|
|
172
172
|
</span>
|
|
173
|
-
<span className="mt-0.5 block text-
|
|
173
|
+
<span className="mt-0.5 block text-og-sm text-og-fg-muted">
|
|
174
174
|
Optional. Enables computer-use — the agent can move the pointer, type, and click on this machine's desktop. Leave
|
|
175
175
|
off to let it only watch.
|
|
176
176
|
</span>
|
|
177
177
|
</span>
|
|
178
178
|
</label>
|
|
179
179
|
) : (
|
|
180
|
-
<p className="flex items-start gap-2 rounded-og-md border border-og-border bg-og-bg px-3 py-2 text-
|
|
180
|
+
<p className="flex items-start gap-2 rounded-og-md border border-og-border bg-og-bg px-3 py-2 text-og-sm text-og-fg-muted">
|
|
181
181
|
<CircleAlertIcon className="mt-px size-3.5 shrink-0 text-og-fg-subtle" aria-hidden />
|
|
182
182
|
This machine has no display, so screen control isn't available — files, terminal, and git only.
|
|
183
183
|
</p>
|
|
@@ -189,7 +189,7 @@ export function EnrollmentConsent({
|
|
|
189
189
|
data-deny
|
|
190
190
|
disabled={busy}
|
|
191
191
|
onClick={() => onDeny?.()}
|
|
192
|
-
className="flex-1 rounded-og-sm border border-og-border px-3 py-2 text-sm font-medium text-og-fg-muted transition-colors hover:border-og-border-strong hover:text-og-fg disabled:opacity-50"
|
|
192
|
+
className="flex-1 rounded-og-sm border border-og-border px-3 py-2 text-og-sm font-medium text-og-fg-muted transition-colors hover:border-og-border-strong hover:text-og-fg disabled:opacity-50 pointer-coarse:min-h-10"
|
|
193
193
|
>
|
|
194
194
|
Cancel
|
|
195
195
|
</button>
|
|
@@ -198,7 +198,7 @@ export function EnrollmentConsent({
|
|
|
198
198
|
data-approve
|
|
199
199
|
disabled={busy}
|
|
200
200
|
onClick={() => onApprove?.(allowScreenControl)}
|
|
201
|
-
className="flex-1 rounded-og-sm bg-og-status-failed px-3 py-2 text-sm font-semibold text-
|
|
201
|
+
className="flex-1 rounded-og-sm bg-og-status-failed px-3 py-2 text-og-sm font-semibold text-og-accent-fg transition-colors hover:opacity-90 disabled:opacity-50 pointer-coarse:min-h-10"
|
|
202
202
|
>
|
|
203
203
|
{busy ? "Connecting…" : "Grant full access"}
|
|
204
204
|
</button>
|
|
@@ -238,8 +238,8 @@ function ConsentResult({
|
|
|
238
238
|
<span className={cn("flex size-10 items-center justify-center rounded-full bg-og-surface-2", iconClass)}>
|
|
239
239
|
<LaptopIcon className="size-5" aria-hidden />
|
|
240
240
|
</span>
|
|
241
|
-
<h1 className="text-
|
|
242
|
-
<p className="max-w-sm text-
|
|
241
|
+
<h1 className="text-og-md font-semibold text-og-fg">{title}</h1>
|
|
242
|
+
<p className="max-w-sm text-og-base text-og-fg-muted">{body}</p>
|
|
243
243
|
</div>
|
|
244
244
|
);
|
|
245
245
|
}
|