@opengeni/react 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +109 -2
  2. package/dist/chunk-DEW2ZNF2.js +1238 -0
  3. package/dist/chunk-DEW2ZNF2.js.map +1 -0
  4. package/dist/index.d.ts +191 -61
  5. package/dist/index.js +1501 -1009
  6. package/dist/index.js.map +1 -1
  7. package/dist/machines-BD6h9P_s.d.ts +329 -0
  8. package/dist/machines.d.ts +4 -0
  9. package/dist/machines.js +33 -0
  10. package/dist/machines.js.map +1 -0
  11. package/package.json +8 -2
  12. package/src/client.ts +1 -0
  13. package/src/components/desktop-viewer.tsx +11 -1
  14. package/src/components/enrollment-consent.tsx +245 -0
  15. package/src/components/enrollment-device-flow.tsx +182 -0
  16. package/src/components/fleet-tile.tsx +5 -0
  17. package/src/components/machine-card.tsx +131 -0
  18. package/src/components/machine-dock-bar.tsx +84 -0
  19. package/src/components/machine-metrics.tsx +184 -0
  20. package/src/components/machine-status-pill.tsx +157 -0
  21. package/src/components/machines-dashboard.tsx +151 -0
  22. package/src/components/message-timeline.tsx +106 -8
  23. package/src/components/workspace-dock.tsx +44 -10
  24. package/src/hooks/use-codex-accounts.ts +179 -0
  25. package/src/hooks/use-desktop-stream.ts +28 -2
  26. package/src/hooks/use-goal.ts +10 -2
  27. package/src/hooks/use-machines.ts +157 -0
  28. package/src/hooks/use-relay-frame-stream.ts +335 -0
  29. package/src/hooks/use-session.ts +80 -12
  30. package/src/index.ts +16 -1
  31. package/src/lib/git-patch.ts +10 -4
  32. package/src/lib/relay-wire.ts +116 -0
  33. package/src/machines.ts +50 -0
  34. package/src/timeline/activity-rail.tsx +13 -7
  35. package/src/timeline/index.ts +1 -0
  36. package/src/timeline/parsers.ts +6 -1
  37. package/src/timeline/projection.ts +203 -16
  38. package/src/timeline/turn-summary.tsx +32 -10
  39. package/src/timeline/types.ts +29 -3
  40. package/src/types/machines.ts +67 -0
package/dist/index.d.ts CHANGED
@@ -1,54 +1,41 @@
1
- import { OpenGeniClient, Session, ResourceRef, ToolRef, SessionStatus as SessionStatus$1, SessionEvent, GitFileDiff, StreamConnectionState, SendMessageInput, FileAsset, FileResourceRef, SessionTurn, UpdateSessionTurnRequest, SessionGoal, ScheduledTask, WorkspaceEnvironment, CreateWorkspaceEnvironmentRequest, UpdateWorkspaceEnvironmentRequest, WorkspaceEnvironmentVariableMetadata, CapabilityPack, PackInstallation, RegisterCapabilityPackRequest, WorkspaceRegisteredPack, EnablePackRequest, Workspace, CreateWorkspaceRequest, UpdateWorkspaceRequest, BillingBalance, UsageEvent, ClientModel, SessionCapabilities, DesktopStreamCapability, DesktopRfbFactory, DesktopConnectionState, TerminalCapability, FsReadResponse, FsWriteResponse, Permission, CapabilityUnavailableReason } from '@opengeni/sdk';
2
- import * as react_jsx_runtime from 'react/jsx-runtime';
1
+ import { C as ClientOverride, S as SessionClientLike } from './machines-BD6h9P_s.js';
2
+ export { a as CONNECTION_STATUS_META, b as ConnectionDot, c as ConnectionDotProps, d as ConnectionStatus, e as ConnectionStatusMeta, f as ConnectionStatusPill, g as ConnectionStatusPillProps, D as DeviceFlowPhase, E as EnrollmentConsent, h as EnrollmentConsentMachine, i as EnrollmentConsentPhase, j as EnrollmentConsentProps, k as EnrollmentDeviceFlow, l as EnrollmentDeviceFlowProps, M as MACHINE_STATE_BADGE_META, m as MachineCard, n as MachineCardProps, o as MachineDockBar, p as MachineDockBarProps, q as MachineMetrics, r as MachineMetricsProps, s as MachineStateBadgeMeta, t as MachineStatusPill, u as MachineStatusPillProps, v as MachinesClientLike, w as MachinesDashboard, x as MachinesDashboardProps, O as OpenGeniContextValue, y as OpenGeniProvider, z as OpenGeniProviderProps, A as SharedMachineDisclosure, B as SharedMachineDisclosureProps, U as UseMachinesOptions, F as UseMachinesResult, G as connectionStatusForState, H as useMachines, I as useOpenGeni, J as useOpenGeniClient } from './machines-BD6h9P_s.js';
3
+ import { SessionEvent, Session, ResourceRef, ToolRef, SessionStatus as SessionStatus$1, GitFileDiff, StreamConnectionState, SendMessageInput, FileAsset, FileResourceRef, SessionTurn, UpdateSessionTurnRequest, SessionGoal, ScheduledTask, WorkspaceEnvironment, CreateWorkspaceEnvironmentRequest, UpdateWorkspaceEnvironmentRequest, WorkspaceEnvironmentVariableMetadata, CapabilityPack, PackInstallation, RegisterCapabilityPackRequest, WorkspaceRegisteredPack, EnablePackRequest, Workspace, CreateWorkspaceRequest, UpdateWorkspaceRequest, BillingBalance, UsageEvent, ClientModel, SessionCapabilities, DesktopStreamCapability, DesktopConnectionState, DesktopRfbFactory, TerminalCapability, FsReadResponse, FsWriteResponse, Permission, CapabilityUnavailableReason, CodexAccountsResponse, CodexAccount, CodexRotationSettings } from '@opengeni/sdk';
4
+ export { MachineKind, MachineMetricsSeriesResponse, MachineState, MachineView, MachinesResponse, MetricSample } from '@opengeni/sdk';
3
5
  import * as react from 'react';
4
- import { ReactNode, ComponentType, RefObject, KeyboardEvent, ClipboardEvent } from 'react';
6
+ import { ComponentType, ReactNode, RefObject, KeyboardEvent, ClipboardEvent } from 'react';
7
+ import * as react_jsx_runtime from 'react/jsx-runtime';
5
8
  import { ClassValue } from 'clsx';
6
9
 
7
- /**
8
- * The slice of `OpenGeniClient` the hooks depend on. Structural, so apps can
9
- * pass the real SDK client, a proxy-backed client that routes through their
10
- * own API, or a scripted client in tests/demos.
11
- */
12
- type SessionClientLike = Pick<OpenGeniClient, "getClientConfig" | "getSession" | "listSessions" | "sendMessage" | "steerMessage" | "interrupt" | "sendApprovalDecision" | "streamEvents" | "listTurns" | "updateQueuedTurn" | "reorderQueuedTurns" | "deleteQueuedTurn" | "getGoal" | "updateGoal" | "clearSessionContext" | "compactSessionContext" | "listScheduledTasks" | "uploadFile" | "getFile" | "createFileDownloadUrl" | "listEnvironments" | "createEnvironment" | "updateEnvironment" | "deleteEnvironment" | "setEnvironmentVariable" | "deleteEnvironmentVariable" | "listPacks" | "registerPack" | "enablePack" | "deletePack" | "listWorkspaces" | "createWorkspace" | "updateWorkspace" | "getBillingUsage" | "getClientConfig" | "getStreamCapabilities" | "acknowledgeStream" | "attachViewer" | "heartbeatViewer" | "detachViewer" | "fsList" | "fsRead" | "fsWrite" | "fsDelete" | "fsMove" | "fsMkdir" | "gitStatus" | "gitDiff" | "terminalExec" | "terminalPtyOpen" | "terminalPtyWrite" | "terminalPtyResize" | "terminalPtyClose">;
13
-
14
- type OpenGeniContextValue = {
15
- client: SessionClientLike;
16
- workspaceId: string;
17
- };
18
- type OpenGeniProviderProps = {
19
- client: SessionClientLike;
20
- workspaceId: string;
21
- children?: ReactNode;
22
- };
23
- /**
24
- * Supplies the OpenGeni client + workspace to all hooks below it. Hooks also
25
- * accept `{ client, workspaceId }` overrides per call for multi-workspace UIs.
26
- */
27
- declare function OpenGeniProvider({ client, workspaceId, children }: OpenGeniProviderProps): react_jsx_runtime.JSX.Element;
28
- type ClientOverride = {
29
- client?: SessionClientLike | undefined;
30
- workspaceId?: string | undefined;
10
+ type SessionEventFeedOptions = {
11
+ /**
12
+ * Share an existing event log (from `useSessionEvents`) instead of opening
13
+ * a second stream. When omitted the hook tails the session's event stream
14
+ * itself, starting at the current `lastSequence`.
15
+ */
16
+ events?: SessionEvent[] | undefined;
17
+ enabled?: boolean | undefined;
31
18
  };
32
- /** Resolve client + workspace from explicit overrides or the provider. */
33
- declare function useOpenGeni(override?: ClientOverride): OpenGeniContextValue;
34
- /**
35
- * Resolve the client only — for hooks that are not workspace-scoped
36
- * (`useWorkspaces`, `useBillingUsage`).
37
- */
38
- declare function useOpenGeniClient(override?: Pick<ClientOverride, "client">): SessionClientLike;
39
19
 
40
- type UseSessionOptions = ClientOverride & {
20
+ type UseSessionOptions = ClientOverride & SessionEventFeedOptions & {
41
21
  /** Re-fetch on an interval (ms). Off by default — pair with `useSessionEvents` for live status. */
42
22
  pollIntervalMs?: number | undefined;
43
- enabled?: boolean | undefined;
44
23
  };
45
24
  type UseSessionResult = {
46
25
  session: Session | null;
47
26
  loading: boolean;
48
27
  error: Error | null;
49
28
  refresh: () => Promise<void>;
29
+ /** Manually rename the session (PATCH, source='user'). Returns the updated session, or null on failure. */
30
+ updateTitle: (title: string) => Promise<Session | null>;
31
+ /** True while a rename is in flight. */
32
+ updating: boolean;
33
+ mutationError: Error | null;
34
+ clearMutationError: () => void;
50
35
  };
51
- /** Fetch one session (with optional polling). */
36
+ /** Event types that change the session title (auto + cross-client renames). */
37
+ declare function isTitleEvent(event: Pick<SessionEvent, "type">): boolean;
38
+ /** Fetch one session (with optional polling), live-patching its title on `session.title_set`. */
52
39
  declare function useSession(sessionId: string | null | undefined, options?: UseSessionOptions): UseSessionResult;
53
40
 
54
41
  type UserMessageItem = {
@@ -107,11 +94,16 @@ type WorkerItem = {
107
94
  id: string;
108
95
  turnId: string | null;
109
96
  callId: string | null;
110
- action: "spawn" | "message";
97
+ action: "spawn" | "message" | "interrupt";
111
98
  /** The worker's initial message / the message sent to it, when parseable. */
112
99
  prompt: string | null;
113
100
  /** The target/spawned worker session id, when parseable from args/output. */
114
101
  workerSessionId: string | null;
102
+ /**
103
+ * For an `interrupt` action, whether it stops the target (default) or steers
104
+ * it (cancel the current turn, keep the goal). Absent on spawn/message.
105
+ */
106
+ mode?: "stop" | "steer";
115
107
  status: "running" | "complete" | "failed" | "cancelled";
116
108
  occurredAt: string;
117
109
  };
@@ -145,7 +137,16 @@ type NoticeItem = {
145
137
  text: string;
146
138
  occurredAt: string;
147
139
  };
148
- type TimelineItem = UserMessageItem | AgentMessageItem | ReasoningItem | ToolCallItem | WorkerItem | SandboxItem | SessionStatusItem | GoalItem | NoticeItem;
140
+ type TurnOutcome = "complete" | "failed" | "cancelled";
141
+ type TurnEndItem = {
142
+ kind: "turn-end";
143
+ id: string;
144
+ turnId: string | null;
145
+ outcome: TurnOutcome;
146
+ failureText: string | null;
147
+ occurredAt: string;
148
+ };
149
+ type TimelineItem = UserMessageItem | AgentMessageItem | ReasoningItem | ToolCallItem | WorkerItem | SandboxItem | SessionStatusItem | GoalItem | NoticeItem | TurnEndItem;
149
150
  /** Activity items cluster between chat messages (reasoning, tools, workers, sandbox). */
150
151
  type ActivityItem = ReasoningItem | ToolCallItem | WorkerItem | SandboxItem;
151
152
  type TimelineGroup = {
@@ -155,6 +156,16 @@ type TimelineGroup = {
155
156
  kind: "activity";
156
157
  id: string;
157
158
  items: ActivityItem[];
159
+ outcome?: TurnOutcome;
160
+ failureText?: string;
161
+ } | {
162
+ kind: "turn";
163
+ id: string;
164
+ outcome: TurnOutcome;
165
+ failureText?: string;
166
+ startedAt: string;
167
+ endedAt: string;
168
+ groups: TimelineGroup[];
158
169
  };
159
170
 
160
171
  declare function buildTimeline(events: SessionEvent[]): TimelineItem[];
@@ -383,19 +394,20 @@ declare function DisclosureDefaultsProvider({ defaultOpen, children }: {
383
394
  children: ReactNode;
384
395
  }): react_jsx_runtime.JSX.Element;
385
396
 
386
- type TurnOutcome = "complete" | "failed" | "cancelled";
387
397
  type TurnSummaryProps = {
388
398
  /** The activity items in the turn (used only to compute the facet counts). */
389
399
  items: ActivityItem[];
390
400
  outcome: TurnOutcome;
391
401
  /** A short failure reason shown inline on a failed chip (never hidden). */
392
402
  failureText?: string | undefined;
403
+ /** Elapsed turn duration; shown as a trailing facet when at least 1s. */
404
+ durationMs?: number | undefined;
393
405
  /** Start expanded. */
394
406
  defaultOpen?: boolean | undefined;
395
407
  /** The rendered activity rail revealed on expand. */
396
408
  children: React.ReactNode;
397
409
  };
398
- declare function TurnSummary({ items, outcome, failureText, defaultOpen, children }: TurnSummaryProps): react_jsx_runtime.JSX.Element;
410
+ declare function TurnSummary({ items, outcome, failureText, durationMs, defaultOpen, children }: TurnSummaryProps): react_jsx_runtime.JSX.Element;
399
411
 
400
412
  /** Recover the exit code from a sandbox exec banner (`Process exited with code N`). */
401
413
  declare function sandboxCommandExitCode(out: unknown): number | null;
@@ -607,16 +619,6 @@ type UseFileAttachmentsResult = {
607
619
  */
608
620
  declare function useFileAttachments(options?: UseFileAttachmentsOptions): UseFileAttachmentsResult;
609
621
 
610
- type SessionEventFeedOptions = {
611
- /**
612
- * Share an existing event log (from `useSessionEvents`) instead of opening
613
- * a second stream. When omitted the hook tails the session's event stream
614
- * itself, starting at the current `lastSequence`.
615
- */
616
- events?: SessionEvent[] | undefined;
617
- enabled?: boolean | undefined;
618
- };
619
-
620
622
  /** Event types that change the turn queue (queue/edit/reorder/claim/finish). */
621
623
  declare function isTurnQueueEvent(event: Pick<SessionEvent, "type">): boolean;
622
624
  /** Queued turns in execution order (position, then creation time). */
@@ -950,16 +952,71 @@ type UseSessionCapabilitiesResult = {
950
952
  */
951
953
  declare function useSessionCapabilities(sessionId: string | null | undefined, options?: UseSessionCapabilitiesOptions): UseSessionCapabilitiesResult;
952
954
 
955
+ /**
956
+ * The minimal WebSocket surface the frame renderer drives. Lets tests (and a
957
+ * future transport swap) inject a fake without a live socket — the exact
958
+ * analogue of `DesktopRfbFactory` for the noVNC path. Structurally a subset of
959
+ * the browser `WebSocket`.
960
+ */
961
+ interface DesktopWebSocketLike {
962
+ binaryType: string;
963
+ send(data: ArrayBuffer): void;
964
+ close(): void;
965
+ addEventListener(type: "open" | "message" | "error" | "close", listener: (ev: {
966
+ data?: unknown;
967
+ } & Record<string, unknown>) => void): void;
968
+ removeEventListener(type: "open" | "message" | "error" | "close", listener: (ev: {
969
+ data?: unknown;
970
+ } & Record<string, unknown>) => void): void;
971
+ }
972
+ type DesktopWebSocketFactory = (url: string) => DesktopWebSocketLike;
973
+ type UseRelayFrameStreamOptions = {
974
+ /** The desktop cell of the negotiated capabilities (`capabilities.DesktopStream`). */
975
+ capability: DesktopStreamCapability | null;
976
+ /** The mount target. A `<canvas>` is appended here on connect. */
977
+ containerRef: RefObject<HTMLDivElement | null>;
978
+ /** Custom socket factory (tests / a transport swap). Defaults to `new WebSocket(url)`. */
979
+ webSocketFactory?: DesktopWebSocketFactory | undefined;
980
+ };
981
+ type UseRelayFrameStreamResult = {
982
+ state: DesktopConnectionState;
983
+ error: Error | null;
984
+ /** Tear down + reopen the socket (e.g. after a drop, once a fresh url arrives). */
985
+ reconnect: () => void;
986
+ };
987
+ /**
988
+ * VIEW-ONLY PNG-frame renderer for a SELF-HOSTED desktop stream — the relay
989
+ * transport (`transport: "relay-frames"`, `client: "frames"`). The self-hosted
990
+ * agent produces one PNG per frame as a protobuf datagram over the relay; there
991
+ * is no RFB/noVNC here. This hook opens the relay DESKTOP channel as a CLIENT
992
+ * (mirroring the proven diagnostic wire protocol), decodes each PNG onto a
993
+ * `<canvas>` mounted into `containerRef`, and drives the connection state
994
+ * machine: idle → connecting (ws opening) → connected (first painted frame) →
995
+ * error (ws error/close/ack rejection).
996
+ *
997
+ * It is DORMANT for any other transport (or no url): it stays idle and touches
998
+ * nothing, so the noVNC path owns the surface. SSR-safe: the socket + DOM attach
999
+ * live inside `useEffect`.
1000
+ *
1001
+ * Backpressure (critical — frames are ~1.8MB at ~10fps): at most one frame is
1002
+ * decoded at a time; a frame arriving mid-decode replaces the pending one
1003
+ * (latest-wins), so a slow decode can never build an unbounded queue.
1004
+ */
1005
+ declare function useRelayFrameStream(options: UseRelayFrameStreamOptions): UseRelayFrameStreamResult;
1006
+
953
1007
  type UseDesktopStreamOptions = {
954
1008
  /** The desktop cell of the negotiated capabilities (`capabilities.DesktopStream`). */
955
1009
  capability: DesktopStreamCapability | null;
956
- /** The mount target. RFB attaches here on connect. */
1010
+ /** The mount target. RFB (or the frame canvas) attaches here on connect. */
957
1011
  containerRef: RefObject<HTMLDivElement | null>;
958
1012
  /** Read-only by default (v1 ruling H). interactive only when cap.mode allows. */
959
1013
  interactive?: boolean | undefined;
960
1014
  scaleViewport?: boolean | undefined;
961
1015
  /** Custom RFB factory (tests / a WebRTC swap). Defaults to a lazy @novnc/novnc. */
962
1016
  rfbFactory?: DesktopRfbFactory | undefined;
1017
+ /** Custom socket factory for the `relay-frames` transport (tests). Defaults to
1018
+ * `new WebSocket(url)`. Mirrors `rfbFactory` for the frame renderer. */
1019
+ webSocketFactory?: DesktopWebSocketFactory | undefined;
963
1020
  };
964
1021
  type UseDesktopStreamResult = {
965
1022
  state: DesktopConnectionState;
@@ -977,6 +1034,14 @@ type UseDesktopStreamResult = {
977
1034
  * `interactive` prop → `RFB.viewOnly`. v1 always resolves to read-only. On a
978
1035
  * capability `url` change (a rotation), the old RFB disconnects and a fresh one
979
1036
  * connects to the new URL — a brief "desktop blink", acceptable on rollover.
1037
+ *
1038
+ * Transport dispatch: a Modal box negotiates `transport: "vnc-ws"` and drives the
1039
+ * noVNC RFB below. A SELF-HOSTED machine negotiates `transport: "relay-frames"`
1040
+ * (PNG-per-frame over the relay, view-only) — that path is delegated to
1041
+ * `useRelayFrameStream`, which paints a `<canvas>`. Both hooks are ALWAYS called
1042
+ * (rules of hooks); each is dormant for the other's transport, and we return the
1043
+ * result of whichever owns the surface. The public interface is identical either
1044
+ * way, so `DesktopViewer` is transport-agnostic.
980
1045
  */
981
1046
  declare function useDesktopStream(options: UseDesktopStreamOptions): UseDesktopStreamResult;
982
1047
 
@@ -1867,6 +1932,9 @@ type DesktopViewerProps = {
1867
1932
  scaleViewport?: boolean | undefined;
1868
1933
  /** Custom RFB factory (tests / a WebRTC swap). Defaults to lazy @novnc/novnc. */
1869
1934
  rfbFactory?: DesktopRfbFactory | undefined;
1935
+ /** Custom socket factory for the self-hosted `relay-frames` transport (tests).
1936
+ * Defaults to `new WebSocket(url)`. Mirrors `rfbFactory`. */
1937
+ webSocketFactory?: DesktopWebSocketFactory | undefined;
1870
1938
  /**
1871
1939
  * Consent gate for the un-redacted (and possibly shared) pixel plane. Rendered
1872
1940
  * BEFORE connecting whenever the desktop requires acknowledgment that hasn't
@@ -1930,7 +1998,7 @@ type DesktopViewerProps = {
1930
1998
  * cold it re-warms. Genuinely-unavailable surfaces (headless/policy/os/backend)
1931
1999
  * keep a clear, static unavailable notice.
1932
2000
  */
1933
- declare function DesktopViewer({ capability, interactive, showControlToggle, scaleViewport, rfbFactory, renderConsentGate, onAcknowledge, watching, onWarm, renderUnavailable, renderWarming, renderViewerCap, viewerCapReached, connectTimeoutMs, className, }: DesktopViewerProps): react_jsx_runtime.JSX.Element;
2001
+ declare function DesktopViewer({ capability, interactive, showControlToggle, scaleViewport, rfbFactory, webSocketFactory, renderConsentGate, onAcknowledge, watching, onWarm, renderUnavailable, renderWarming, renderViewerCap, viewerCapReached, connectTimeoutMs, className, }: DesktopViewerProps): react_jsx_runtime.JSX.Element;
1934
2002
 
1935
2003
  type WorkspaceTab = {
1936
2004
  id: string;
@@ -1947,6 +2015,9 @@ type WorkspaceDockProps = {
1947
2015
  /** Controlled active tab. Falls back to the first tab. */
1948
2016
  activeTab?: string | undefined;
1949
2017
  onActiveTabChange?: ((id: string) => void) | undefined;
2018
+ /** Controlled collapsed state for hosts that expose their own dock toggle. */
2019
+ collapsed?: boolean | undefined;
2020
+ onCollapsedChange?: ((collapsed: boolean) => void) | undefined;
1950
2021
  /** Persisted layout id (localStorage key) for react-resizable-panels. */
1951
2022
  autoSaveId?: string | undefined;
1952
2023
  /** Default dock width as a percent of the session area. */
@@ -1955,15 +2026,74 @@ type WorkspaceDockProps = {
1955
2026
  maxSize?: number | undefined;
1956
2027
  className?: string | undefined;
1957
2028
  };
2029
+ declare function WorkspaceDock({ primary, tabs, activeTab, onActiveTabChange, collapsed: collapsedProp, onCollapsedChange, autoSaveId, defaultSize, minSize, maxSize, className, }: WorkspaceDockProps): react_jsx_runtime.JSX.Element;
2030
+
2031
+ /** Events that change which Codex account a session runs on (or just ran). */
2032
+ declare function isCodexAccountEvent(event: Pick<SessionEvent, "type">): boolean;
2033
+ /**
2034
+ * The structural slice of the SDK client the Codex-accounts surface needs. Method
2035
+ * NAMES + SIGNATURES match `OpenGeniClient` so the real client satisfies it
2036
+ * directly; declared structurally (not a hard Pick) so a test/Geni client can
2037
+ * stand in. `getSession` reads the session's pin/last; `pinSessionCodexAccount`
2038
+ * is the optional mutation (absent ⇒ the indicator hides the switch affordance).
2039
+ */
2040
+ type CodexAccountsClientLike = {
2041
+ listCodexAccounts: (workspaceId: string) => Promise<CodexAccountsResponse>;
2042
+ getSession?: (workspaceId: string, sessionId: string) => Promise<{
2043
+ codexPinnedCredentialId?: string | null;
2044
+ codexLastCredentialId?: string | null;
2045
+ }>;
2046
+ pinSessionCodexAccount?: (workspaceId: string, sessionId: string, target: string) => Promise<{
2047
+ pinned: string;
2048
+ }>;
2049
+ /** Optional (absent ⇒ the card hides live refresh): batched live /wham/usage refresh. */
2050
+ refreshCodexUsage?: (workspaceId: string) => Promise<{
2051
+ usage: Record<string, unknown>;
2052
+ }>;
2053
+ };
2054
+ type UseCodexAccountsOptions = ClientOverride & SessionEventFeedOptions & {
2055
+ pollIntervalMs?: number | undefined;
2056
+ /** Scope to a session so the hook resolves the pin + the effective account. */
2057
+ sessionId?: string | undefined;
2058
+ /** Override the client with one implementing `CodexAccountsClientLike`. */
2059
+ codexClient?: CodexAccountsClientLike | undefined;
2060
+ };
2061
+ type UseCodexAccountsResult = {
2062
+ accounts: CodexAccount[];
2063
+ /** The workspace ACTIVE account (used when a session is unpinned). */
2064
+ activeAccountId: string | null;
2065
+ /** The session's PINNED account (null ⇒ following workspace active). */
2066
+ pinnedAccountId: string | null;
2067
+ /** The account the next turn will run on: pin > workspace active. */
2068
+ effectiveAccountId: string | null;
2069
+ /** The account the session's last turn ACTUALLY ran on (the "Running on:" source). */
2070
+ lastAccountId: string | null;
2071
+ settings: CodexRotationSettings;
2072
+ loading: boolean;
2073
+ refresh: () => Promise<void>;
2074
+ /**
2075
+ * Trigger a LIVE batched /wham/usage refresh across all accounts, then re-read
2076
+ * the cached metadata so the new windows land on `accounts`. Modeled on `pin`.
2077
+ * No-op (resolves false) when the client can't refresh usage.
2078
+ */
2079
+ refreshUsage: () => Promise<boolean>;
2080
+ /** True while a live usage refresh is in flight (drives the bar skeleton). */
2081
+ refreshingUsage: boolean;
2082
+ /** Pin (or unpin via "auto") the session's account; returns true on success. */
2083
+ pin: (target: string) => Promise<boolean>;
2084
+ pinning: boolean;
2085
+ /** The target of the in-flight pin (for per-row spinner gating). */
2086
+ pinningTarget: string | null;
2087
+ mutationError: Error | null;
2088
+ };
1958
2089
  /**
1959
- * The resizable / collapsible / maximizable right-hand Workspace dock. Replaces
1960
- * a fixed grid column: drag the separator to set width, collapse to a thin rail
1961
- * that re-opens on click, and maximize to a full-workspace overlay (Esc /
1962
- * restore button returns). Layout persists via `useDefaultLayout` keyed on
1963
- * `autoSaveId`. Maximize is a mode ABOVE the Group (a `fixed inset-0` overlay) —
1964
- * pushing a Panel to ~100% still fights min sizes and leaves a chat sliver.
2090
+ * The workspace's Codex accounts + the per-workspace active pointer + (when
2091
+ * session-scoped) the session pin and last-ran-on account. Composed like
2092
+ * `useMachines`: slow polling (the realtime work is done by the
2093
+ * `codex.account.switched` / `turn.started` event trigger) + a `pin` mutation.
2094
+ * Dual-consumer safe via the structural `CodexAccountsClientLike` surface.
1965
2095
  */
1966
- declare function WorkspaceDock({ primary, tabs, activeTab, onActiveTabChange, autoSaveId, defaultSize, minSize, maxSize, className, }: WorkspaceDockProps): react_jsx_runtime.JSX.Element;
2096
+ declare function useCodexAccounts(options?: UseCodexAccountsOptions): UseCodexAccountsResult;
1967
2097
 
1968
2098
  /**
1969
2099
  * Reconstruct a unified-diff patch string for a single `GitFileDiff` so it can
@@ -1997,4 +2127,4 @@ declare function stringifyPayload(value: unknown): string;
1997
2127
  /** JSON.parse that returns `undefined` instead of throwing. */
1998
2128
  declare function tryParseJson(text: string): unknown;
1999
2129
 
2000
- export { ActivityDisclosure, type ActivityDisclosureProps, type ActivityItem, ActivityRail, type ActivityRailProps, type AgentMessageItem, type ApplyPatchOperation, BodyNote, ChatComposer, type ChatComposerProps, type ClientOverride, CodeEditor, type CodeEditorProps, type CommandContext, CommandPalette, type CommandPaletteProps, type CommandResult, type ComposerMode, type ComposerSendExtras, type ComposerState, type ConfirmState, type CreateToolRegistryOptions, DesktopViewer, type DesktopViewerProps, type DiffTheme, DiffView, type DiffViewProps, type DisclosureChip, DisclosureDefaultsProvider, type FileAttachment, FileBrowser, type FileBrowserProps, type FileTreeNode, type FileTreeStatus, FleetTile, type FleetTileProps, type GoalItem, LightboxProvider, Markdown, type MarkdownProps, MediaEmpty, MediaSkeleton, MessageTimeline, type MessageTimelineProps, ModelPicker, type ModelPickerProps, type Notice, type NoticeItem, type OpenGeniContextValue, OpenGeniProvider, type OpenGeniProviderProps, type ParsedCommandLine, PayloadBlock, type PendingApproval, PierreDiff, type PierreDiffProps, PierreFile, type PierreFileProps, type ReasoningItem, SESSION_STATUS_META, SandboxFiles, type SandboxFilesProps, type SandboxItem, SandboxTerminal, type SandboxTerminalProps, ScreenshotFigure, type SessionCapabilitiesState, type SessionClientLike, type SessionEventsConnectionState, SessionStatus, type SessionStatusItem, type SessionStatusMeta, type SessionStatusProps, type SlashArg, type SlashCommand, type SlashCommandContext, type SlashCommandHandlers, StatusDot, type StatusDotProps, TermBlock, type TerminalChunk, type TerminalStreamStatus, Thumbnail, type TimelineGroup, type TimelineItem, TimelineRow, type ToolCallItem, type ToolRegistry, type ToolRegistryEntry, type ToolRenderer, type ToolRendererProps, type TurnOutcome, TurnSummary, type TurnSummaryProps, type UseAvailableModelsOptions, type UseAvailableModelsResult, type UseBillingUsageOptions, type UseBillingUsageResult, type UseComposerOptions, type UseDesktopStreamOptions, type UseDesktopStreamResult, type UseEnvironmentsOptions, type UseEnvironmentsResult, type UseFileAttachmentsOptions, type UseFileAttachmentsResult, type UseGoalOptions, type UseGoalResult, type UsePacksOptions, type UsePacksResult, type UseSandboxFilesOptions, type UseSandboxFilesResult, type UseSandboxGitOptions, type UseSandboxGitResult, type UseSandboxTerminalOptions, type UseSandboxTerminalResult, type UseScheduledTasksOptions, type UseScheduledTasksResult, type UseSessionCapabilitiesOptions, type UseSessionCapabilitiesResult, type UseSessionControlOptions, type UseSessionControlResult, type UseSessionEventsOptions, type UseSessionEventsResult, type UseSessionOptions, type UseSessionResult, type UseSlashCommandsOptions, type UseSlashCommandsResult, type UseTerminalStreamOptions, type UseTerminalStreamResult, type UseTurnQueueOptions, type UseTurnQueueResult, type UseWorkspaceSessionsOptions, type UseWorkspaceSessionsResult, type UseWorkspacesOptions, type UseWorkspacesResult, type UserMessageItem, type WorkerItem, WorkspaceDock, type WorkspaceDockProps, type WorkspaceTab, type XtermTheme, activeTurnFromTurns, applyPatchOps, applyTurnEdit, applyTurnRemoval, applyTurnReorder, approvalsFromRequiresAction, argHint, buildTimeline, cn, composeSendInput, controlCaret, createDefaultToolRegistry, createToolRegistry, defaultCommands, defaultToolRegistry, execTruncated, extractSessionRef, filterCommands, firstMissingRequiredArg, formatBytes, formatRelativeTime, gitFileDiffToPatch, groupTimeline, hasPermission, isApplyPatch, isExecSessionLostBanner, isGoalEvent, isTurnQueueEvent, languageForPath, looksBinary, matchCommand, parseCommandLine, parseExecBannerSessionId, parseToolArgs, projectPendingApprovals, queueFromTurns, rawTypeOf, redactSecrets, sandboxCommandExitCode, sessionDisplayTitle, sessionStatusFromEvents, shouldSubmitOnKey, stringifyPayload, stripExecBanner, tailPeek, toolDisplayName, truncate, tryParseJson, unwrapMcpOutput, useAvailableModels, useBillingUsage, useComposer, useDesktopStream, useEnvironments, useFileAttachments, useGoal, useLightbox, useLightboxOptional, useOpenGeni, useOpenGeniClient, usePacks, useSandboxFiles, useSandboxGit, useSandboxTerminal, useScheduledTasks, useSession, useSessionCapabilities, useSessionControl, useSessionEvents, useSlashCommands, useTerminalStream, useTurnQueue, useWorkspaceSessions, useWorkspaces, v4aToGitFileDiff, xtermThemeFromTokens };
2130
+ export { ActivityDisclosure, type ActivityDisclosureProps, type ActivityItem, ActivityRail, type ActivityRailProps, type AgentMessageItem, type ApplyPatchOperation, BodyNote, ChatComposer, type ChatComposerProps, ClientOverride, CodeEditor, type CodeEditorProps, type CodexAccountsClientLike, type CommandContext, CommandPalette, type CommandPaletteProps, type CommandResult, type ComposerMode, type ComposerSendExtras, type ComposerState, type ConfirmState, type CreateToolRegistryOptions, DesktopViewer, type DesktopViewerProps, type DesktopWebSocketFactory, type DesktopWebSocketLike, type DiffTheme, DiffView, type DiffViewProps, type DisclosureChip, DisclosureDefaultsProvider, type FileAttachment, FileBrowser, type FileBrowserProps, type FileTreeNode, type FileTreeStatus, FleetTile, type FleetTileProps, type GoalItem, LightboxProvider, Markdown, type MarkdownProps, MediaEmpty, MediaSkeleton, MessageTimeline, type MessageTimelineProps, ModelPicker, type ModelPickerProps, type Notice, type NoticeItem, type ParsedCommandLine, PayloadBlock, type PendingApproval, PierreDiff, type PierreDiffProps, PierreFile, type PierreFileProps, type ReasoningItem, SESSION_STATUS_META, SandboxFiles, type SandboxFilesProps, type SandboxItem, SandboxTerminal, type SandboxTerminalProps, ScreenshotFigure, type SessionCapabilitiesState, SessionClientLike, type SessionEventsConnectionState, SessionStatus, type SessionStatusItem, type SessionStatusMeta, type SessionStatusProps, type SlashArg, type SlashCommand, type SlashCommandContext, type SlashCommandHandlers, StatusDot, type StatusDotProps, TermBlock, type TerminalChunk, type TerminalStreamStatus, Thumbnail, type TimelineGroup, type TimelineItem, TimelineRow, type ToolCallItem, type ToolRegistry, type ToolRegistryEntry, type ToolRenderer, type ToolRendererProps, type TurnEndItem, type TurnOutcome, TurnSummary, type TurnSummaryProps, type UseAvailableModelsOptions, type UseAvailableModelsResult, type UseBillingUsageOptions, type UseBillingUsageResult, type UseCodexAccountsOptions, type UseCodexAccountsResult, type UseComposerOptions, type UseDesktopStreamOptions, type UseDesktopStreamResult, type UseEnvironmentsOptions, type UseEnvironmentsResult, type UseFileAttachmentsOptions, type UseFileAttachmentsResult, type UseGoalOptions, type UseGoalResult, type UsePacksOptions, type UsePacksResult, type UseRelayFrameStreamOptions, type UseRelayFrameStreamResult, type UseSandboxFilesOptions, type UseSandboxFilesResult, type UseSandboxGitOptions, type UseSandboxGitResult, type UseSandboxTerminalOptions, type UseSandboxTerminalResult, type UseScheduledTasksOptions, type UseScheduledTasksResult, type UseSessionCapabilitiesOptions, type UseSessionCapabilitiesResult, type UseSessionControlOptions, type UseSessionControlResult, type UseSessionEventsOptions, type UseSessionEventsResult, type UseSessionOptions, type UseSessionResult, type UseSlashCommandsOptions, type UseSlashCommandsResult, type UseTerminalStreamOptions, type UseTerminalStreamResult, type UseTurnQueueOptions, type UseTurnQueueResult, type UseWorkspaceSessionsOptions, type UseWorkspaceSessionsResult, type UseWorkspacesOptions, type UseWorkspacesResult, type UserMessageItem, type WorkerItem, WorkspaceDock, type WorkspaceDockProps, type WorkspaceTab, type XtermTheme, activeTurnFromTurns, applyPatchOps, applyTurnEdit, applyTurnRemoval, applyTurnReorder, approvalsFromRequiresAction, argHint, buildTimeline, cn, composeSendInput, controlCaret, createDefaultToolRegistry, createToolRegistry, defaultCommands, defaultToolRegistry, execTruncated, extractSessionRef, filterCommands, firstMissingRequiredArg, formatBytes, formatRelativeTime, gitFileDiffToPatch, groupTimeline, hasPermission, isApplyPatch, isCodexAccountEvent, isExecSessionLostBanner, isGoalEvent, isTitleEvent, isTurnQueueEvent, languageForPath, looksBinary, matchCommand, parseCommandLine, parseExecBannerSessionId, parseToolArgs, projectPendingApprovals, queueFromTurns, rawTypeOf, redactSecrets, sandboxCommandExitCode, sessionDisplayTitle, sessionStatusFromEvents, shouldSubmitOnKey, stringifyPayload, stripExecBanner, tailPeek, toolDisplayName, truncate, tryParseJson, unwrapMcpOutput, useAvailableModels, useBillingUsage, useCodexAccounts, useComposer, useDesktopStream, useEnvironments, useFileAttachments, useGoal, useLightbox, useLightboxOptional, usePacks, useRelayFrameStream, useSandboxFiles, useSandboxGit, useSandboxTerminal, useScheduledTasks, useSession, useSessionCapabilities, useSessionControl, useSessionEvents, useSlashCommands, useTerminalStream, useTurnQueue, useWorkspaceSessions, useWorkspaces, v4aToGitFileDiff, xtermThemeFromTokens };