@opengeni/react 6.1.0 → 7.0.0-canary.35625901699001

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 (214) hide show
  1. package/README.md +83 -2
  2. package/dist/approvals.d.ts +2 -1
  3. package/dist/artifacts-document.js +1 -1
  4. package/dist/artifacts-presentation.js +1 -1
  5. package/dist/artifacts-spreadsheet.js +1 -1
  6. package/dist/artifacts.js +3 -3
  7. package/dist/{browser-viewer-NTD6UIPR.js → browser-viewer-LGH4IP47.js} +3 -3
  8. package/dist/capability-catalog-row.d.ts +20 -0
  9. package/dist/capability-logo-fallback.d.ts +3 -0
  10. package/dist/{chunk-NOSYBS2D.js → chunk-2VHARTBL.js} +2 -1
  11. package/dist/{chunk-VRBL3F5E.js → chunk-5GAL23FF.js} +10 -2
  12. package/dist/{chunk-VRBL3F5E.js.map → chunk-5GAL23FF.js.map} +1 -1
  13. package/dist/chunk-5UONOQ3Y.js +635 -0
  14. package/dist/chunk-5UONOQ3Y.js.map +1 -0
  15. package/dist/{chunk-NYESIADM.js → chunk-AKOMC3VO.js} +3 -3
  16. package/dist/chunk-AKOMC3VO.js.map +1 -0
  17. package/dist/chunk-BRM6FVZA.js +302 -0
  18. package/dist/chunk-BRM6FVZA.js.map +1 -0
  19. package/dist/{chunk-KANFU34B.js → chunk-DBPVUGQT.js} +11 -2
  20. package/dist/chunk-DBPVUGQT.js.map +1 -0
  21. package/dist/chunk-FHIGTPME.js +1589 -0
  22. package/dist/chunk-FHIGTPME.js.map +1 -0
  23. package/dist/{chunk-5M6VTFJ5.js → chunk-GBPCZH3Y.js} +2 -2
  24. package/dist/{chunk-YBM6CQRU.js → chunk-GEN54DU5.js} +4 -4
  25. package/dist/{chunk-UMECRJRV.js → chunk-HJ5VJ4JB.js} +21 -12
  26. package/dist/chunk-HJ5VJ4JB.js.map +1 -0
  27. package/dist/{chunk-R4KRSFGA.js → chunk-IP4BUBKH.js} +3 -3
  28. package/dist/{chunk-NLTS7JHI.js → chunk-JPHDWKZE.js} +5 -5
  29. package/dist/{chunk-TDSEILUH.js → chunk-MI6ALLLD.js} +1297 -1535
  30. package/dist/chunk-MI6ALLLD.js.map +1 -0
  31. package/dist/{chunk-ICA6R6TW.js → chunk-OWHPKAOV.js} +28 -20
  32. package/dist/chunk-OWHPKAOV.js.map +1 -0
  33. package/dist/{chunk-24M4YBCL.js → chunk-PNAVEK2U.js} +4 -4
  34. package/dist/{chunk-L2NBTKRX.js → chunk-TXCBE32L.js} +203 -19
  35. package/dist/chunk-TXCBE32L.js.map +1 -0
  36. package/dist/{chunk-45XEUVTK.js → chunk-UXE5SSNN.js} +293 -463
  37. package/dist/chunk-UXE5SSNN.js.map +1 -0
  38. package/dist/{chunk-PEI6RANI.js → chunk-VR4Z73EU.js} +203 -9
  39. package/dist/chunk-VR4Z73EU.js.map +1 -0
  40. package/dist/{chunk-HUIKIDM5.js → chunk-XMXRI5JK.js} +65 -18
  41. package/dist/chunk-XMXRI5JK.js.map +1 -0
  42. package/dist/client.d.ts +1 -1
  43. package/dist/components/artifacts/spreadsheet-general-display.d.ts +24 -0
  44. package/dist/components/chat-composer.d.ts +13 -3
  45. package/dist/components/markdown.d.ts +6 -3
  46. package/dist/components/message-timeline.d.ts +7 -2
  47. package/dist/components/preview-loading.d.ts +2 -0
  48. package/dist/components/session-capability-frame.d.ts +24 -0
  49. package/dist/components/session-chrome.d.ts +1 -2
  50. package/dist/components/session-commands.d.ts +6 -0
  51. package/dist/components/session-connection-request.d.ts +8 -0
  52. package/dist/components/session-conversation.d.ts +3 -0
  53. package/dist/components/session-mcp-capability-card.d.ts +22 -0
  54. package/dist/components/timeline-search.d.ts +34 -0
  55. package/dist/composer.js +7 -7
  56. package/dist/connect-account-identity.d.ts +8 -0
  57. package/dist/connect-accounts.d.ts +5 -0
  58. package/dist/connect-chooser.d.ts +6 -0
  59. package/dist/connect-panel.d.ts +9 -2
  60. package/dist/connect-setup.d.ts +5 -1
  61. package/dist/connect.d.ts +5 -21
  62. package/dist/connect.js +1268 -584
  63. package/dist/connect.js.map +1 -1
  64. package/dist/connection-catalog.d.ts +6 -1
  65. package/dist/connection-discovery.d.ts +12 -0
  66. package/dist/connection-installed.d.ts +1 -0
  67. package/dist/connection-logo.d.ts +5 -2
  68. package/dist/connection-service-logo.d.ts +8 -0
  69. package/dist/connection-service-presentation.d.ts +13 -0
  70. package/dist/connection-skeleton.d.ts +5 -0
  71. package/dist/discovery-cache.d.ts +5 -0
  72. package/dist/hooks/use-codex-accounts.d.ts +11 -5
  73. package/dist/hooks/use-connect.d.ts +22 -0
  74. package/dist/hooks/use-session-events.d.ts +5 -0
  75. package/dist/hooks/use-session-mcp-approval-policy.d.ts +2 -2
  76. package/dist/hooks/use-workspace-sessions.d.ts +2 -0
  77. package/dist/index.d.ts +8 -2
  78. package/dist/index.js +771 -793
  79. package/dist/index.js.map +1 -1
  80. package/dist/interaction.js +2 -2
  81. package/dist/machines.js +2 -2
  82. package/dist/mcp-connection-status.d.ts +14 -0
  83. package/dist/{model-policy-picker-menu-3R336DP2.js → model-policy-picker-menu-RVOQ4ZZG.js} +4 -4
  84. package/dist/model-policy.d.ts +6 -2
  85. package/dist/model-policy.js +1 -1
  86. package/dist/{platform-activity-row-DUE2W74J.js → platform-activity-row-HLOH7FW4.js} +9 -4
  87. package/dist/platform-activity-row-HLOH7FW4.js.map +1 -0
  88. package/dist/plugin-discovery.d.ts +6 -0
  89. package/dist/{queue-surface-implementation-LK3S4BIW.js → queue-surface-implementation-3RIFK2BS.js} +4 -4
  90. package/dist/realtime.js +22 -22
  91. package/dist/realtime.js.map +1 -1
  92. package/dist/session-auth-recommendation.d.ts +5 -0
  93. package/dist/session-capability-policy.d.ts +12 -0
  94. package/dist/session-ui.d.ts +2 -0
  95. package/dist/session-ui.js +14 -12
  96. package/dist/session.d.ts +1 -0
  97. package/dist/session.js +6 -4
  98. package/dist/skill-discovery.d.ts +11 -0
  99. package/dist/timeline/compaction-copy.d.ts +10 -0
  100. package/dist/timeline/projection.d.ts +3 -1
  101. package/dist/timeline/tool-display-name.d.ts +2 -1
  102. package/dist/timeline/turn-summary.d.ts +2 -2
  103. package/dist/timeline/types.d.ts +24 -2
  104. package/dist/{timeline-annotation-markers-DRSTLEM6.js → timeline-annotation-markers-OY6OWR3V.js} +2 -2
  105. package/dist/{timeline-annotation-selection-IHLUGVND.js → timeline-annotation-selection-BOXA2TIN.js} +2 -2
  106. package/dist/{timeline-annotations-dialog-6Q53N5FG.js → timeline-annotations-dialog-RGY3MHL3.js} +3 -3
  107. package/package.json +3 -3
  108. package/src/approvals.ts +8 -1
  109. package/src/assets/README.md +8 -0
  110. package/src/assets/gmail.ico +0 -0
  111. package/src/assets/outlook.ico +0 -0
  112. package/src/capability-catalog-row.tsx +94 -0
  113. package/src/capability-logo-fallback.ts +22 -0
  114. package/src/client.ts +0 -9
  115. package/src/components/approval-surface.tsx +12 -2
  116. package/src/components/artifacts/document-editor.tsx +63 -6
  117. package/src/components/artifacts/presentation-editor.tsx +214 -9
  118. package/src/components/artifacts/spreadsheet-canvas.ts +3 -8
  119. package/src/components/artifacts/spreadsheet-general-display.ts +43 -0
  120. package/src/components/artifacts/spreadsheet-grid.tsx +10 -11
  121. package/src/components/chat-composer.tsx +26 -3
  122. package/src/components/composer.tsx +10 -4
  123. package/src/components/human-input-form.tsx +12 -2
  124. package/src/components/markdown.tsx +133 -9
  125. package/src/components/message-timeline.tsx +104 -36
  126. package/src/components/model-picker.tsx +11 -3
  127. package/src/components/model-policy-picker-menu.tsx +10 -3
  128. package/src/components/preview-loading.tsx +154 -0
  129. package/src/components/sandbox-workspace.tsx +20 -36
  130. package/src/components/session-capability-frame.tsx +163 -0
  131. package/src/components/session-chrome.tsx +46 -77
  132. package/src/components/session-commands.tsx +18 -0
  133. package/src/components/session-connection-request.tsx +97 -0
  134. package/src/components/session-conversation.tsx +10 -5
  135. package/src/components/session-mcp-capability-card.tsx +532 -0
  136. package/src/components/session-status.tsx +2 -2
  137. package/src/components/timeline-anchor.tsx +9 -8
  138. package/src/components/timeline-search.tsx +168 -0
  139. package/src/components/user-message-body.tsx +7 -0
  140. package/src/connect-account-identity.tsx +34 -0
  141. package/src/connect-accounts.tsx +114 -52
  142. package/src/connect-chooser.tsx +171 -39
  143. package/src/connect-panel.tsx +73 -9
  144. package/src/connect-setup.tsx +72 -25
  145. package/src/connect.ts +13 -22
  146. package/src/connection-assets.d.ts +4 -0
  147. package/src/connection-catalog.tsx +61 -39
  148. package/src/connection-discovery.tsx +235 -0
  149. package/src/connection-installed.tsx +2 -0
  150. package/src/connection-logo.tsx +18 -10
  151. package/src/connection-service-logo.tsx +55 -0
  152. package/src/connection-service-presentation.ts +46 -0
  153. package/src/connection-skeleton.tsx +16 -0
  154. package/src/conversation-timeline.ts +1 -0
  155. package/src/discovery-cache.ts +42 -0
  156. package/src/hooks/use-codex-accounts.ts +33 -14
  157. package/src/hooks/use-composer.ts +4 -5
  158. package/src/hooks/use-connect.ts +23 -0
  159. package/src/hooks/use-session-events.ts +114 -1
  160. package/src/hooks/use-session-mcp-approval-policy.ts +13 -5
  161. package/src/hooks/use-workspace-sessions.ts +10 -0
  162. package/src/index.ts +22 -2
  163. package/src/mcp-connection-status.ts +35 -0
  164. package/src/model-policy.ts +21 -0
  165. package/src/plugin-details.tsx +8 -5
  166. package/src/plugin-discovery.tsx +92 -72
  167. package/src/realtime/realtime-control.tsx +6 -8
  168. package/src/session-auth-recommendation.ts +48 -0
  169. package/src/session-capability-policy.ts +83 -0
  170. package/src/session-ui.ts +2 -0
  171. package/src/session.ts +1 -0
  172. package/src/skill-discovery.tsx +101 -56
  173. package/src/timeline/compaction-copy.ts +40 -0
  174. package/src/timeline/platform-activity-row.tsx +8 -3
  175. package/src/timeline/projection.ts +78 -2
  176. package/src/timeline/rolling-activity.tsx +4 -2
  177. package/src/timeline/shared.tsx +6 -1
  178. package/src/timeline/startup-timings.tsx +1 -1
  179. package/src/timeline/tool-display-name.ts +8 -6
  180. package/src/timeline/tool-renderers.tsx +5 -3
  181. package/src/timeline/turn-summary.tsx +17 -3
  182. package/src/timeline/types.ts +24 -2
  183. package/styles/compiled.css +325 -27
  184. package/styles/connect.css +90 -15
  185. package/styles/index.css +46 -0
  186. package/styles/session-capability.css +42 -0
  187. package/dist/chunk-45XEUVTK.js.map +0 -1
  188. package/dist/chunk-HQV2I5HV.js +0 -124
  189. package/dist/chunk-HQV2I5HV.js.map +0 -1
  190. package/dist/chunk-HUIKIDM5.js.map +0 -1
  191. package/dist/chunk-ICA6R6TW.js.map +0 -1
  192. package/dist/chunk-IHQII5WO.js +0 -886
  193. package/dist/chunk-IHQII5WO.js.map +0 -1
  194. package/dist/chunk-KANFU34B.js.map +0 -1
  195. package/dist/chunk-L2NBTKRX.js.map +0 -1
  196. package/dist/chunk-NYESIADM.js.map +0 -1
  197. package/dist/chunk-PEI6RANI.js.map +0 -1
  198. package/dist/chunk-TDSEILUH.js.map +0 -1
  199. package/dist/chunk-UMECRJRV.js.map +0 -1
  200. package/dist/hooks/use-packs.d.ts +0 -32
  201. package/dist/platform-activity-row-DUE2W74J.js.map +0 -1
  202. package/src/hooks/use-packs.ts +0 -157
  203. /package/dist/{browser-viewer-NTD6UIPR.js.map → browser-viewer-LGH4IP47.js.map} +0 -0
  204. /package/dist/{chunk-NOSYBS2D.js.map → chunk-2VHARTBL.js.map} +0 -0
  205. /package/dist/{chunk-5M6VTFJ5.js.map → chunk-GBPCZH3Y.js.map} +0 -0
  206. /package/dist/{chunk-YBM6CQRU.js.map → chunk-GEN54DU5.js.map} +0 -0
  207. /package/dist/{chunk-R4KRSFGA.js.map → chunk-IP4BUBKH.js.map} +0 -0
  208. /package/dist/{chunk-NLTS7JHI.js.map → chunk-JPHDWKZE.js.map} +0 -0
  209. /package/dist/{chunk-24M4YBCL.js.map → chunk-PNAVEK2U.js.map} +0 -0
  210. /package/dist/{model-policy-picker-menu-3R336DP2.js.map → model-policy-picker-menu-RVOQ4ZZG.js.map} +0 -0
  211. /package/dist/{queue-surface-implementation-LK3S4BIW.js.map → queue-surface-implementation-3RIFK2BS.js.map} +0 -0
  212. /package/dist/{timeline-annotation-markers-DRSTLEM6.js.map → timeline-annotation-markers-OY6OWR3V.js.map} +0 -0
  213. /package/dist/{timeline-annotation-selection-IHLUGVND.js.map → timeline-annotation-selection-BOXA2TIN.js.map} +0 -0
  214. /package/dist/{timeline-annotations-dialog-6Q53N5FG.js.map → timeline-annotations-dialog-RGY3MHL3.js.map} +0 -0
@@ -94,7 +94,6 @@ export type SessionChromeAgentsSignal = {
94
94
  };
95
95
 
96
96
  export type SessionChromeProps = {
97
- compact?: boolean;
98
97
  /** Authoritative execution status; omitted by older embedding hosts. */
99
98
  sessionStatus?: SessionStatus | undefined;
100
99
  queue: UseTurnQueueResult;
@@ -432,7 +431,6 @@ function toneClass(tone: SessionChromeSignalTone, selected: boolean): string {
432
431
  }
433
432
 
434
433
  export function SessionChrome({
435
- compact = false,
436
434
  sessionStatus,
437
435
  queue,
438
436
  composer,
@@ -451,7 +449,7 @@ export function SessionChrome({
451
449
  onActiveChange,
452
450
  }: SessionChromeProps) {
453
451
  const [activityRequested, setActivityOpen] = useState(
454
- Boolean(compact && defaultActive && ["incoming", "agents", "commands"].includes(defaultActive)),
452
+ Boolean(defaultActive && ["incoming", "agents", "commands"].includes(defaultActive)),
455
453
  );
456
454
  const reactId = useId();
457
455
  const panelId = `og-session-chrome-panel-${reactId}`;
@@ -499,8 +497,7 @@ export function SessionChrome({
499
497
  );
500
498
  const active = activeControlled !== undefined ? activeControlled : activeUncontrolled;
501
499
  const activityOpen =
502
- activityRequested ||
503
- Boolean(compact && active && ["incoming", "agents", "commands"].includes(active));
500
+ activityRequested || Boolean(active && ["incoming", "agents", "commands"].includes(active));
504
501
  const activityVisibleRef = useRef(activityOpen);
505
502
  activityVisibleRef.current = activityOpen;
506
503
  // Two independent suppressions, both occupancy-scoped:
@@ -711,12 +708,9 @@ export function SessionChrome({
711
708
 
712
709
  const signalIds = signals.map((signal) => signal.id).join(",");
713
710
  useEffect(() => {
714
- if (
715
- compact &&
716
- !signals.some((signal) => ["incoming", "agents", "commands"].includes(signal.id))
717
- )
711
+ if (!signals.some((signal) => ["incoming", "agents", "commands"].includes(signal.id)))
718
712
  setActivityOpen(false);
719
- }, [compact, signals]);
713
+ }, [signals]);
720
714
  useEffect(() => {
721
715
  if (active && !signalIds.split(",").includes(active)) {
722
716
  if (activeControlled === undefined) setActiveUncontrolled(null);
@@ -885,21 +879,9 @@ export function SessionChrome({
885
879
  )}
886
880
  style={{
887
881
  borderRadius: "var(--_og-session-chrome-radius)",
888
- background: compact
889
- ? "transparent"
890
- : open
891
- ? "var(--_og-session-chrome-surface-open)"
892
- : "var(--_og-session-chrome-surface)",
893
- borderColor: compact
894
- ? "transparent"
895
- : open
896
- ? "var(--_og-session-chrome-border-open)"
897
- : "var(--_og-session-chrome-border)",
898
- boxShadow: compact
899
- ? "none"
900
- : open
901
- ? "var(--og-session-chrome-shadow-open)"
902
- : "var(--og-session-chrome-shadow)",
882
+ background: "transparent",
883
+ borderColor: "transparent",
884
+ boxShadow: "none",
903
885
  transitionDuration: "var(--og-session-chrome-duration)",
904
886
  transitionTimingFunction: "var(--_og-session-chrome-ease)",
905
887
  }}
@@ -915,9 +897,9 @@ export function SessionChrome({
915
897
  >
916
898
  <div
917
899
  ref={railRef}
918
- className={cn("relative flex items-center", compact ? "flex-nowrap" : "flex-wrap")}
900
+ className="relative flex flex-nowrap items-center"
919
901
  style={{
920
- gap: compact ? "10px" : "var(--og-session-chrome-chip-gap)",
902
+ gap: "10px",
921
903
  }}
922
904
  >
923
905
  <motion.div
@@ -938,9 +920,7 @@ export function SessionChrome({
938
920
  transition={{ duration: shellDuration, ease }}
939
921
  />
940
922
  {signals
941
- .filter(
942
- (signal) => !compact || !["incoming", "agents", "commands"].includes(signal.id),
943
- )
923
+ .filter((signal) => !["incoming", "agents", "commands"].includes(signal.id))
944
924
  .map((signal) => {
945
925
  const selected = active === signal.id;
946
926
  return (
@@ -956,8 +936,8 @@ export function SessionChrome({
956
936
  }
957
937
  className={cn(
958
938
  "group/signal relative z-[1] inline-flex min-w-0 max-w-full items-center rounded-og-md",
959
- compact && "bg-og-surface-2/60 px-0.5",
960
- compact && selected && "bg-og-surface-3",
939
+ "bg-og-surface-2/60 px-0.5",
940
+ selected && "bg-og-surface-3",
961
941
  )}
962
942
  >
963
943
  <button
@@ -968,7 +948,7 @@ export function SessionChrome({
968
948
  aria-expanded={selected}
969
949
  aria-controls={panelId}
970
950
  aria-label={
971
- compact && signal.id === "goal"
951
+ signal.id === "goal"
972
952
  ? `Goal · ${goalState === "pursuing" ? "Running" : signal.label}`
973
953
  : selected
974
954
  ? `Close ${signal.label}`
@@ -976,9 +956,9 @@ export function SessionChrome({
976
956
  }
977
957
  data-testid={`session-chrome-${signal.id}`}
978
958
  data-og-session-chrome-signal={signal.id}
979
- title={signal.title ?? (compact ? signal.label : undefined)}
959
+ title={signal.title ?? signal.label}
980
960
  onClick={() => {
981
- if (compact) setActivityOpen(false);
961
+ setActivityOpen(false);
982
962
  setActive(selected ? null : signal.id);
983
963
  }}
984
964
  className={cn(
@@ -1007,43 +987,21 @@ export function SessionChrome({
1007
987
  <span className={cn("shrink-0", toneClass(signal.tone, selected))}>
1008
988
  {signal.icon}
1009
989
  </span>
1010
- <span
1011
- className={cn(
1012
- "font-medium text-og-fg",
1013
- compact ? "min-w-0 truncate" : "shrink-0",
1014
- )}
1015
- >
1016
- {compact && signal.id === "goal" ? "Goal · " : null}
1017
- {compact && signal.id === "goal"
990
+ <span className={cn("font-medium text-og-fg", "min-w-0 truncate")}>
991
+ {signal.id === "goal" ? "Goal · " : null}
992
+ {signal.id === "goal"
1018
993
  ? goalState === "pursuing"
1019
994
  ? "Running"
1020
995
  : signal.label
1021
- : compact && signal.id === "queue"
1022
- ? `${queuedTurns.length + optimisticQueued.length} queued`
996
+ : signal.id === "queue"
997
+ ? queue.error || queue.mutationError
998
+ ? signal.label
999
+ : `${queuedTurns.length + optimisticQueued.length} queued`
1023
1000
  : signal.label}
1024
1001
  </span>
1025
- {signal.detail && !compact ? (
1026
- <>
1027
- <span aria-hidden className="shrink-0 text-og-fg-subtle/60">
1028
- ·
1029
- </span>
1030
- <span className="min-w-0 max-w-[8.5rem] truncate text-og-fg sm:max-w-[12rem]">
1031
- {signal.detail}
1032
- </span>
1033
- </>
1034
- ) : null}
1035
- {selected && !compact ? (
1036
- <span
1037
- data-testid="session-chrome-close"
1038
- className="ml-0.5 inline-flex size-4 shrink-0 items-center justify-center rounded-og-sm text-og-fg-subtle transition-colors group-hover:text-og-fg pointer-coarse:size-5"
1039
- aria-hidden
1040
- >
1041
- <XIcon className="size-3" />
1042
- </span>
1043
- ) : null}
1044
1002
  </button>
1045
1003
  {signal.id === "goal" && goal && record && !readOnly ? (
1046
- <div className={cn("flex shrink-0 items-center pr-1", compact && "pl-0.5")}>
1004
+ <div className="flex shrink-0 items-center pr-1 pl-0.5">
1047
1005
  {record.status === "active" || record.status === "paused" ? (
1048
1006
  <IconAction
1049
1007
  label={record.status === "paused" ? "Resume goal" : "Pause goal"}
@@ -1075,7 +1033,7 @@ export function SessionChrome({
1075
1033
  </IconAction>
1076
1034
  </div>
1077
1035
  ) : signal.id === "queue" && canMutateQueue && queuedTurns[0] ? (
1078
- <div className={cn("flex shrink-0 items-center pr-1", compact && "pl-0.5")}>
1036
+ <div className="flex shrink-0 items-center pr-1 pl-0.5">
1079
1037
  <IconAction
1080
1038
  label="Steer first queued message"
1081
1039
  text="Steer"
@@ -1092,11 +1050,11 @@ export function SessionChrome({
1092
1050
  </div>
1093
1051
  );
1094
1052
  })}
1095
- {compact &&
1096
- signals.some((signal) => ["incoming", "agents", "commands"].includes(signal.id)) ? (
1053
+ {signals.some((signal) => ["incoming", "agents", "commands"].includes(signal.id)) ? (
1097
1054
  <button
1098
1055
  type="button"
1099
1056
  aria-label="Session activity"
1057
+ aria-describedby={commandsCount > 0 ? `${panelId}-commands-count` : undefined}
1100
1058
  title={activityOpen ? "Close activity" : "Inbox, agents and commands"}
1101
1059
  aria-controls={panelId}
1102
1060
  aria-expanded={activityOpen}
@@ -1105,9 +1063,11 @@ export function SessionChrome({
1105
1063
  setActive(
1106
1064
  activityOpen
1107
1065
  ? null
1108
- : (signals.find((signal) =>
1109
- ["incoming", "agents", "commands"].includes(signal.id),
1110
- )?.id ?? null),
1066
+ : commandsCount > 0 && hasCommandsPanel
1067
+ ? "commands"
1068
+ : (signals.find((signal) =>
1069
+ ["incoming", "agents", "commands"].includes(signal.id),
1070
+ )?.id ?? null),
1111
1071
  );
1112
1072
  }}
1113
1073
  className={cn(
@@ -1119,6 +1079,17 @@ export function SessionChrome({
1119
1079
  >
1120
1080
  <ActivityIcon className="size-3.5" />
1121
1081
  <span className="sr-only">Activity</span>
1082
+ {commandsCount > 0 ? (
1083
+ <>
1084
+ <span
1085
+ aria-hidden="true"
1086
+ className="size-1.5 shrink-0 animate-og-pulse rounded-full bg-og-fg-muted motion-reduce:animate-none"
1087
+ />
1088
+ <span id={`${panelId}-commands-count`}>
1089
+ {commandsCount} command{commandsCount === 1 ? "" : "s"}
1090
+ </span>
1091
+ </>
1092
+ ) : null}
1122
1093
  {incoming.length > 0 ? (
1123
1094
  <span className="size-1.5 rounded-full bg-og-accent" />
1124
1095
  ) : null}
@@ -1142,7 +1113,7 @@ export function SessionChrome({
1142
1113
  </div>
1143
1114
 
1144
1115
  <AnimatePresence initial={false}>
1145
- {compact && activityOpen ? (
1116
+ {activityOpen ? (
1146
1117
  <motion.div
1147
1118
  key="activity-tabs"
1148
1119
  initial={{ height: 0, opacity: 0 }}
@@ -1201,11 +1172,9 @@ export function SessionChrome({
1201
1172
  <div
1202
1173
  className={cn(
1203
1174
  "relative overflow-y-auto overscroll-contain",
1204
- compact
1205
- ? activityOpen
1206
- ? "rounded-b-og-lg bg-og-surface-2/50"
1207
- : "mt-1 rounded-og-lg bg-og-surface-2/50"
1208
- : "border-t border-og-border/50",
1175
+ activityOpen
1176
+ ? "rounded-b-og-lg bg-og-surface-2/50"
1177
+ : "mt-1 rounded-og-lg bg-og-surface-2/50",
1209
1178
  )}
1210
1179
  style={{
1211
1180
  maxHeight: "var(--og-session-chrome-panel-max-height)",
@@ -0,0 +1,18 @@
1
+ import {
2
+ useSessionBackgroundCommands,
3
+ type UseSessionBackgroundCommandsOptions,
4
+ } from "../hooks/use-session-background-commands";
5
+ import { SessionCommandsPanel } from "./session-commands-panel";
6
+
7
+ /** Mount in the open activity panel so closed chrome never polls commands. */
8
+ export function SessionCommands({
9
+ sessionId,
10
+ readOnly = false,
11
+ ...options
12
+ }: UseSessionBackgroundCommandsOptions & { sessionId: string; readOnly?: boolean }) {
13
+ const commands = useSessionBackgroundCommands(sessionId, {
14
+ pollIntervalMs: 3_000,
15
+ ...options,
16
+ });
17
+ return <SessionCommandsPanel commands={commands} readOnly={readOnly} />;
18
+ }
@@ -0,0 +1,97 @@
1
+ import { useEffect, useRef, useState } from "react";
2
+ import type { AuthNeededItem } from "../timeline/types";
3
+ import { sessionAuthRecommendation } from "../session-auth-recommendation";
4
+ import {
5
+ SessionMcpCapabilityCard,
6
+ type SessionMcpCapabilityCardProps,
7
+ } from "./session-mcp-capability-card";
8
+
9
+ export type SessionConnectionRequestProps = Omit<
10
+ SessionMcpCapabilityCardProps,
11
+ "capabilityId" | "name" | "rationale"
12
+ > & {
13
+ request: AuthNeededItem;
14
+ };
15
+
16
+ /** Resolve native reauthorization notices with the same exact-identity rules
17
+ * as the console. Recommendations never supply endpoints or account authority. */
18
+ export function SessionConnectionRequest(props: SessionConnectionRequestProps) {
19
+ const [client, setClient] = useState(props.client);
20
+ const [generation, setGeneration] = useState(0);
21
+ if (client !== props.client) {
22
+ setClient(props.client);
23
+ setGeneration(generation + 1);
24
+ }
25
+ return (
26
+ <ScopedRequest
27
+ key={`${generation}:${props.workspaceId}:${props.sessionId}:${props.request.id}`}
28
+ {...props}
29
+ />
30
+ );
31
+ }
32
+
33
+ function ScopedRequest({ request, ...props }: SessionConnectionRequestProps) {
34
+ const [resolved, setResolved] = useState<AuthNeededItem | null>(null);
35
+ const [error, setError] = useState<string | null>(null);
36
+ const [retry, setRetry] = useState(0);
37
+ const requestRef = useRef(request);
38
+ requestRef.current = request;
39
+ useEffect(() => {
40
+ let current = true;
41
+ const event = requestRef.current;
42
+ setResolved(null);
43
+ setError(null);
44
+ void props.client
45
+ .listCapabilities(props.workspaceId)
46
+ .then((catalog) => {
47
+ if (!current) return;
48
+ const recommendation = sessionAuthRecommendation(event, catalog.items);
49
+ const candidate = catalog.items.find(
50
+ (entry) => entry.id === recommendation?.capability?.id,
51
+ );
52
+ if (!recommendation || candidate?.kind !== "mcp" || candidate.authKind !== "oauth2") {
53
+ setError(
54
+ "This request could not be matched to one available OAuth integration. Review its connection settings before continuing.",
55
+ );
56
+ return;
57
+ }
58
+ setResolved(recommendation);
59
+ })
60
+ .catch(() => {
61
+ if (current)
62
+ setError("Couldn't load connection details. Retry to check the current integration.");
63
+ });
64
+ return () => {
65
+ current = false;
66
+ };
67
+ }, [
68
+ props.client,
69
+ props.workspaceId,
70
+ request.id,
71
+ request.serverId,
72
+ request.connectionId,
73
+ request.authoritySource,
74
+ request.reason,
75
+ request.capability?.id,
76
+ retry,
77
+ ]);
78
+ if (!resolved?.capability)
79
+ return (
80
+ <div className="og-session-capability-setup">
81
+ <p role={error ? "alert" : "status"}>{error ?? "Loading connection details…"}</p>
82
+ {error ? (
83
+ <button type="button" onClick={() => setRetry((value) => value + 1)}>
84
+ Retry
85
+ </button>
86
+ ) : null}
87
+ </div>
88
+ );
89
+ return (
90
+ <SessionMcpCapabilityCard
91
+ {...props}
92
+ capabilityId={resolved.capability.id}
93
+ name={resolved.capability.name}
94
+ rationale={resolved.capability.rationale}
95
+ />
96
+ );
97
+ }
@@ -8,15 +8,17 @@ import { useTurnQueue } from "../hooks/use-turn-queue";
8
8
  import { useComposer } from "../hooks/use-composer";
9
9
  import { useHumanInputRequests } from "../hooks/use-human-input";
10
10
  import { ChatComposer, type ChatComposerProps } from "./chat-composer";
11
- import { QueueSurface } from "./queue-surface";
11
+ import { SessionChrome } from "./session-chrome";
12
12
  import { HumanInputSurface, type HumanInputSurfaceProps } from "./human-input-surface";
13
- import { MessageTimeline } from "./message-timeline";
13
+ import { MessageTimeline, type MessageTimelineProps } from "./message-timeline";
14
14
  import type { UserMessageDisclosureLabels } from "./user-message-body";
15
15
  import { conversationTimeline } from "../conversation-timeline";
16
16
  import { cn } from "../lib/cn";
17
17
 
18
18
  export type SessionConversationProps = ClientOverride & {
19
19
  sessionId: string;
20
+ /** Host-owned artifact links, previews and other message presentation. */
21
+ renderMessageText?: MessageTimelineProps["renderMessageText"];
20
22
  /** Localized actions for already-sent user-message disclosure. */
21
23
  userMessageDisclosureLabels?: UserMessageDisclosureLabels | undefined;
22
24
  loadSkillReview?: HumanInputSurfaceProps["loadSkillReview"];
@@ -35,6 +37,7 @@ export function SessionConversation(props: SessionConversationProps) {
35
37
 
36
38
  function Conversation({
37
39
  sessionId,
40
+ renderMessageText,
38
41
  userMessageDisclosureLabels,
39
42
  loadSkillReview,
40
43
  client,
@@ -75,6 +78,7 @@ function Conversation({
75
78
  >
76
79
  {error && <p role="alert">{error.message}</p>}
77
80
  <MessageTimeline
81
+ renderMessageText={renderMessageText}
78
82
  userMessageDisclosureLabels={userMessageDisclosureLabels}
79
83
  className="min-h-0 flex-1"
80
84
  items={conversationTimeline(feed.timeline, queue, composer)}
@@ -104,12 +108,13 @@ function Conversation({
104
108
  autoFocus={false}
105
109
  />
106
110
  {terminal ? (
107
- <QueueSurface queue={queue} readOnly />
111
+ <SessionChrome queue={queue} sessionStatus={status} readOnly />
108
112
  ) : (
109
- <QueueSurface
113
+ <SessionChrome
110
114
  queue={queue}
111
115
  composer={composer}
112
- onRequestComposerFocus={() =>
116
+ sessionStatus={status}
117
+ onComposerFocus={() =>
113
118
  region.current?.querySelector<HTMLTextAreaElement>("textarea")?.focus()
114
119
  }
115
120
  />