@datalayer/agent-runtimes 1.3.88 → 1.3.90

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 (258) hide show
  1. package/lib/Agent.js +2 -18
  2. package/lib/AgentDocument.js +5 -55
  3. package/lib/AgentNode.js +31 -208
  4. package/lib/AgentNotebook.js +5 -59
  5. package/lib/agent-node/AgentNodeGallery.js +23 -111
  6. package/lib/agents/AgentDetails.js +36 -274
  7. package/lib/agents/AgentRuntimeChat.js +1 -8
  8. package/lib/chat/Chat.js +7 -46
  9. package/lib/chat/ChatFloating.js +15 -100
  10. package/lib/chat/ChatInline.js +5 -47
  11. package/lib/chat/ChatPopupStandalone.js +5 -53
  12. package/lib/chat/ChatSidebar.js +4 -51
  13. package/lib/chat/ChatStandalone.js +4 -45
  14. package/lib/chat/EphemeralSurfaceControl.js +5 -25
  15. package/lib/chat/assistant/AssistantContextMenu.d.ts +8 -0
  16. package/lib/chat/assistant/AssistantContextMenu.js +17 -1
  17. package/lib/chat/assistant/AssistantStage.js +6 -25
  18. package/lib/chat/assistant/BalloonParts.js +8 -40
  19. package/lib/chat/assistant/BalloonVisual.js +2 -2
  20. package/lib/chat/assistant/ConversationBalloon.js +2 -11
  21. package/lib/chat/assistant/DecisionAsk.js +3 -3
  22. package/lib/chat/assistant/SandboxDetailsDialog.js +3 -17
  23. package/lib/chat/assistant/SpeechBalloon.js +14 -78
  24. package/lib/chat/base/ChatBase.js +37 -172
  25. package/lib/chat/display/EmptyState.js +7 -35
  26. package/lib/chat/display/FloatingBrandButton.js +4 -34
  27. package/lib/chat/display/PoweredByTag.js +3 -14
  28. package/lib/chat/document/EphemeralDocument.js +3 -18
  29. package/lib/chat/header/ChatHeader.js +1 -17
  30. package/lib/chat/header/ChatHeaderBase.js +2 -24
  31. package/lib/chat/header/ChatViewModeToggle.js +7 -29
  32. package/lib/chat/indicators/McpStatusIndicator.js +3 -12
  33. package/lib/chat/indicators/SandboxStatusIndicator.js +6 -34
  34. package/lib/chat/indicators/SkillsStatusIndicator.js +3 -12
  35. package/lib/chat/indicators/TypingDots.js +1 -11
  36. package/lib/chat/messages/ChatMessageList.js +58 -185
  37. package/lib/chat/messages/ChatMessages.js +15 -79
  38. package/lib/chat/messages/FormSubmissionMessage.js +2 -33
  39. package/lib/chat/messages/NotebookToolSurfaces.js +12 -41
  40. package/lib/chat/messages/TurnFooter.js +4 -10
  41. package/lib/chat/notebook/EphemeralNotebook.js +2 -10
  42. package/lib/chat/parts/ReasoningPart.js +2 -16
  43. package/lib/chat/parts/TextPart.js +2 -12
  44. package/lib/chat/parts/ToolPart.js +16 -90
  45. package/lib/chat/presence/Presence.js +5 -33
  46. package/lib/chat/prompt/FloatingCard.js +1 -13
  47. package/lib/chat/prompt/InputPrompt.js +1 -6
  48. package/lib/chat/prompt/InputPromptBase.js +4 -17
  49. package/lib/chat/prompt/InputPromptLexical.js +44 -45
  50. package/lib/chat/prompt/InputPromptText.js +1 -1
  51. package/lib/chat/prompt/footer/InPromptFooter.js +1 -8
  52. package/lib/chat/prompt/menus/AgentsMenu.js +1 -1
  53. package/lib/chat/prompt/menus/InlineAgentsMenu.js +1 -1
  54. package/lib/chat/prompt/menus/ModelSelector.js +1 -5
  55. package/lib/chat/prompt/menus/SkillsMenu.js +3 -30
  56. package/lib/chat/prompt/menus/SuggestionsMenu.js +1 -1
  57. package/lib/chat/prompt/menus/ToolsMenu.js +4 -48
  58. package/lib/chat/prompt/plugins/AgentMentionPlugin.js +2 -9
  59. package/lib/chat/prompt/plugins/CommandPlugin.js +2 -9
  60. package/lib/chat/prompt/plugins/MentionChip.js +1 -15
  61. package/lib/chat/prompt/stack.js +1 -19
  62. package/lib/chat/tools/A2AAgentDialog.js +9 -42
  63. package/lib/chat/tools/SubagentActivity.js +5 -22
  64. package/lib/chat/tools/ToolApprovalBanner.js +4 -34
  65. package/lib/chat/tools/ToolApprovalDialog.js +4 -19
  66. package/lib/chat/tools/ToolCallDisplay.js +12 -97
  67. package/lib/chat/usage/ContextPie.js +4 -45
  68. package/lib/components/a2ui/datalayer/Chart.js +4 -10
  69. package/lib/components/a2ui/datalayer/Chat.js +2 -10
  70. package/lib/components/a2ui/datalayer/Download.js +1 -1
  71. package/lib/components/a2ui/datalayer/Evidence.js +1 -15
  72. package/lib/components/a2ui/datalayer/FileUpload.js +1 -12
  73. package/lib/components/a2ui/datalayer/Table.js +9 -17
  74. package/lib/components/a2ui/datalayer/formWidgets.js +3 -2
  75. package/lib/components/a2ui/datalayer/parts.js +1 -16
  76. package/lib/components/agents/AgentSummary.js +1 -51
  77. package/lib/components/cards/NotificationEventCard.js +6 -72
  78. package/lib/components/cards/OutputCard.js +4 -48
  79. package/lib/components/cards/ToolApprovalCard.js +2 -35
  80. package/lib/components/code-sandboxes/CodeSandboxCellVariables.js +1 -1
  81. package/lib/components/code-sandboxes/CodeSandboxEnvironmentSelect.js +4 -14
  82. package/lib/components/code-sandboxes/CodeSandboxPicker.js +16 -21
  83. package/lib/components/code-sandboxes/CodeSandboxVariables.js +2 -2
  84. package/lib/components/scheduler/ScheduleMenu.js +5 -10
  85. package/lib/components/specs/SpecPayloadPreview.js +1 -26
  86. package/lib/components/teams/A2ATeamGraph.d.ts +4 -3
  87. package/lib/components/teams/A2ATeamGraph.js +25 -71
  88. package/lib/components/teams/AnswerSurfacesView.js +2 -2
  89. package/lib/components/teams/NotebookPreview.js +1 -10
  90. package/lib/components/teams/NotebookPreviewView.js +2 -3
  91. package/lib/components/teams/SceneTranscript.js +3 -17
  92. package/lib/components/teams/SceneView.js +1 -8
  93. package/lib/components/teams/TeamNotebook.js +5 -13
  94. package/lib/components/teams/TeamNotebookView.js +2 -12
  95. package/lib/components/teams/index.d.ts +1 -0
  96. package/lib/components/teams/index.js +1 -0
  97. package/lib/components/teams/useBalloonRoom.d.ts +39 -0
  98. package/lib/components/teams/useBalloonRoom.js +89 -0
  99. package/lib/config/AgentConfiguration.js +22 -225
  100. package/lib/context/ContextDistribution.js +7 -41
  101. package/lib/context/ContextInspector.js +9 -107
  102. package/lib/context/ContextPanel.js +11 -86
  103. package/lib/context/ContextUsage.js +6 -34
  104. package/lib/context/CostTracker.js +7 -42
  105. package/lib/context/MessageHistory.js +3 -37
  106. package/lib/context/TurnGraphChart.js +9 -41
  107. package/lib/examples/A2UiAgentExample.js +6 -108
  108. package/lib/examples/A2UiComponentsGalleryExample.js +1 -1
  109. package/lib/examples/A2UiContactCardExample.js +1 -1
  110. package/lib/examples/A2UiJupyterOutputExample.js +25 -125
  111. package/lib/examples/A2UiRestaurantExample.js +1 -1
  112. package/lib/examples/A2UiViewerExample.js +1 -1
  113. package/lib/examples/AgUiAgenticExample.js +3 -35
  114. package/lib/examples/AgUiBackendToolRenderingExample.js +2 -25
  115. package/lib/examples/AgUiHaikuGenUiExample.js +2 -32
  116. package/lib/examples/AgUiHumanInTheLoopExample.js +5 -59
  117. package/lib/examples/AgUiSharedStateExample.js +6 -56
  118. package/lib/examples/AgUiToolsBasedGenUiExample.js +25 -120
  119. package/lib/examples/AgentA2AExample.js +1 -15
  120. package/lib/examples/AgentA2ATeamExample.js +6 -30
  121. package/lib/examples/AgentCheckpointsExample.js +11 -145
  122. package/lib/examples/AgentCodeSandboxExample.js +5 -108
  123. package/lib/examples/AgentCodeSandboxesExample.js +3 -30
  124. package/lib/examples/AgentCodemodeExample.js +9 -85
  125. package/lib/examples/AgentCompactionExample.js +3 -64
  126. package/lib/examples/AgentDecideExample.js +1 -13
  127. package/lib/examples/AgentEvalsExample.js +5 -60
  128. package/lib/examples/AgentGuardrailsExample.js +4 -28
  129. package/lib/examples/AgentHooksExample.js +1 -1
  130. package/lib/examples/AgentInferenceProviderExample.js +5 -96
  131. package/lib/examples/AgentMCPExample.js +7 -105
  132. package/lib/examples/AgentMemoryExample.js +5 -74
  133. package/lib/examples/AgentMonitoringExample.js +7 -53
  134. package/lib/examples/AgentNotificationsExample.js +3 -61
  135. package/lib/examples/AgentOtelExample.js +3 -72
  136. package/lib/examples/AgentOutputsExample.js +6 -81
  137. package/lib/examples/AgentParametersExample.js +2 -37
  138. package/lib/examples/AgentSkillsExample.js +3 -45
  139. package/lib/examples/AgentSubagentsExample.js +6 -56
  140. package/lib/examples/AgentToolApprovalsExample.js +1 -11
  141. package/lib/examples/AgentTriggersExample.js +29 -239
  142. package/lib/examples/AgentspecsExample.js +6 -60
  143. package/lib/examples/AssistantExample.js +5 -5
  144. package/lib/examples/AssistantGalleryExample.js +8 -65
  145. package/lib/examples/CellExample.js +1 -6
  146. package/lib/examples/ChatCustomExample.js +2 -31
  147. package/lib/examples/ChatExample.js +1 -9
  148. package/lib/examples/ChatStandaloneExample.js +3 -37
  149. package/lib/examples/CopilotKitLexicalExample.js +1 -24
  150. package/lib/examples/DecksAgent.js +1 -1
  151. package/lib/examples/DocumentPageAgent.js +1 -1
  152. package/lib/examples/HomeExample.js +14 -62
  153. package/lib/examples/Lexical2Example.js +3 -32
  154. package/lib/examples/LexicalAgentExample.js +2 -34
  155. package/lib/examples/LexicalAgentSidebarExample.js +3 -34
  156. package/lib/examples/LoopAppComputerExample.js +1 -1
  157. package/lib/examples/LoopShellExample.js +2 -2
  158. package/lib/examples/LoopStrategyExample.js +15 -87
  159. package/lib/examples/LoopWorkspaceEmbed.js +2 -18
  160. package/lib/examples/LoopWorkspaceExample.js +2 -2
  161. package/lib/examples/NotebookAgentExample.js +2 -33
  162. package/lib/examples/NotebookAgentSidebarExample.js +3 -46
  163. package/lib/examples/NotebookCollaborationExample.js +1 -31
  164. package/lib/examples/NotebookExample.js +1 -18
  165. package/lib/examples/NotebookPageAgent.js +1 -1
  166. package/lib/examples/ScenesExample.js +5 -24
  167. package/lib/examples/VoiceChatExample.js +1 -1
  168. package/lib/examples/components/AuthRequiredView.js +1 -7
  169. package/lib/examples/components/ErrorView.js +1 -8
  170. package/lib/examples/components/ExampleErrorBoundary.js +1 -14
  171. package/lib/examples/components/FooterMetrics.js +1 -7
  172. package/lib/examples/components/Header.js +12 -51
  173. package/lib/examples/components/HeaderControls.js +1 -9
  174. package/lib/examples/components/LexicalEditor.js +1 -8
  175. package/lib/examples/components/MainContent.js +1 -13
  176. package/lib/examples/components/MockFileBrowser.js +4 -40
  177. package/lib/examples/components/SessionTabs.js +1 -1
  178. package/lib/examples/components/TimeTravel.js +1 -13
  179. package/lib/examples/main.js +13 -81
  180. package/lib/examples/scenes/A2UiComponentsGalleryScene.js +3 -34
  181. package/lib/examples/scenes/A2UiContactCardScene.js +3 -35
  182. package/lib/examples/scenes/A2UiRestaurantScene.js +3 -53
  183. package/lib/examples/scenes/A2UiViewerScene.js +3 -34
  184. package/lib/examples/utils/AssistantGalleryGrid.js +6 -35
  185. package/lib/examples2/DatalayerNotebookExample.js +3 -33
  186. package/lib/examples2/NativeNavigationExample.js +4 -10
  187. package/lib/examples2/NotebookMutationsKernel.js +2 -1
  188. package/lib/examples2/NotebookMutationsServiceManager.js +2 -1
  189. package/lib/examples2/ReactRouterExample.js +14 -42
  190. package/lib/hooks/useToolApprovals.d.ts +2 -34
  191. package/lib/hooks/useToolApprovals.js +1 -64
  192. package/lib/identity/AgentIdentity.js +17 -62
  193. package/lib/identity/IdentityConnect.js +13 -59
  194. package/lib/identity/OAuthCallback.js +6 -44
  195. package/lib/lexical/ChatInlinePlugin.js +6 -14
  196. package/lib/loop/apps/AppRenderer.d.ts +4 -3
  197. package/lib/loop/apps/AppRenderer.js +11 -12
  198. package/lib/loop/apps/appspec.js +6 -3
  199. package/lib/loop/embed/AppEmbed.d.ts +1 -1
  200. package/lib/loop/embed/AppEmbed.js +2 -1
  201. package/lib/loop/embed/LoopEmbed.js +1 -7
  202. package/lib/loop/embed/embedConfig.d.ts +3 -3
  203. package/lib/loop/embed/embedConfig.js +2 -3
  204. package/lib/loop/embed/embedTheme.d.ts +4 -4
  205. package/lib/loop/embed/embedTheme.js +11 -7
  206. package/lib/loop/plugins/a2a-sidebar/A2ASidebar.js +7 -34
  207. package/lib/loop/plugins/a2ui/A2uiView.js +4 -12
  208. package/lib/loop/plugins/a2ui-surface/InlineSurface.js +1 -16
  209. package/lib/loop/plugins/a2ui-surface/SurfaceToolResult.js +2 -12
  210. package/lib/loop/plugins/agents/AnonymousKeyBadge.js +3 -2
  211. package/lib/loop/plugins/agents/SandboxSelector.js +3 -7
  212. package/lib/loop/plugins/agents/SandboxView.js +4 -27
  213. package/lib/loop/plugins/agents/TeamMemberPicker.js +2 -2
  214. package/lib/loop/plugins/agentspecs/AgentspecPicker.js +3 -2
  215. package/lib/loop/plugins/app-activity/AppActivity.js +1 -1
  216. package/lib/loop/plugins/app-computer/AppComputer.js +5 -21
  217. package/lib/loop/plugins/app-elements/AppElements.js +2 -31
  218. package/lib/loop/plugins/app-page/AppPage.js +1 -1
  219. package/lib/loop/plugins/app-rules/AppRulesCard.js +4 -20
  220. package/lib/loop/plugins/assistant/index.js +1 -13
  221. package/lib/loop/plugins/chat/ChatView.js +40 -106
  222. package/lib/loop/plugins/checkpoints-sidebar/CheckpointsSidebar.js +2 -13
  223. package/lib/loop/plugins/decks/DeckSurface.js +2 -2
  224. package/lib/loop/plugins/document/DocumentView.js +4 -12
  225. package/lib/loop/plugins/document-toolbar/SandboxStatusItem.js +3 -8
  226. package/lib/loop/plugins/graph/GraphView.js +2 -2
  227. package/lib/loop/plugins/input-prompt/ComposerView.js +1 -1
  228. package/lib/loop/plugins/notebook/NotebookView.js +3 -11
  229. package/lib/loop/plugins/page-layout/SplitLayout.js +11 -34
  230. package/lib/loop/plugins/page-layout/TurnPanel.js +9 -35
  231. package/lib/loop/plugins/shell/useEditorPreviews.js +3 -2
  232. package/lib/loop/plugins/subagent-activity/SubagentPulse.js +1 -13
  233. package/lib/loop/plugins/window-frame/WindowFrame.js +10 -44
  234. package/lib/loop/plugins/window-frame/index.js +1 -1
  235. package/lib/loop/shell/LoopWorkspace.js +34 -77
  236. package/lib/loop/shell/PluginToggles.js +4 -15
  237. package/lib/loop/shell/SidebarRail.js +8 -40
  238. package/lib/loop/shell/ViewSwitcher.js +4 -24
  239. package/lib/loop-main.js +2 -3
  240. package/lib/mcp/McpServerManager.js +6 -37
  241. package/lib/portable/index.d.ts +11 -0
  242. package/lib/portable/index.js +20 -0
  243. package/lib/protocols/AGUIAdapter.js +2 -2
  244. package/lib/protocols/BaseProtocolAdapter.d.ts +2 -0
  245. package/lib/protocols/BaseProtocolAdapter.js +4 -0
  246. package/lib/specs/apps.js +6 -0
  247. package/lib/specs/appspecSchema.js +11 -4
  248. package/lib/stories/loop/ReferenceScreens.js +17 -91
  249. package/lib/stories/loop/pictures-main.js +1 -1
  250. package/lib/types/agentspecs.d.ts +5 -2
  251. package/lib/types/protocol.d.ts +2 -0
  252. package/lib/utils/approvals.d.ts +59 -0
  253. package/lib/utils/approvals.js +101 -0
  254. package/lib/voice/VoiceInput.js +3 -39
  255. package/package.json +2 -2
  256. package/scripts/codegen/generate_envvars.py +0 -1
  257. package/lib/shims/primerAddonsBox.d.ts +0 -1
  258. package/lib/shims/primerAddonsBox.js +0 -7
@@ -4,7 +4,8 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
4
4
  * Distributed under the terms of the Modified BSD License.
5
5
  */
6
6
  import React, { useCallback } from 'react';
7
- import { Box, Text, Button, Label, Flash, ActionList, ActionMenu, Avatar, } from '@primer/react';
7
+ import { Box } from '@datalayer/primer-addons';
8
+ import { Text, Button, Label, Flash, ActionList, ActionMenu, Avatar, } from '@primer/react';
8
9
  import { MarkGithubIcon, LinkIcon, UnlinkIcon, CheckCircleFillIcon, AlertIcon, KeyIcon, } from '@primer/octicons-react';
9
10
  import { useIdentity } from './useIdentity';
10
11
  import { GITHUB_PROVIDER, GOOGLE_PROVIDER, KAGGLE_PROVIDER } from './types';
@@ -154,39 +155,21 @@ export const IdentityButton = ({ provider, clientId, providerConfig, scopes, dis
154
155
  width: size === 'small' ? 28 : size === 'large' ? 44 : 36,
155
156
  height: size === 'small' ? 28 : size === 'large' ? 44 : 36,
156
157
  p: 0,
157
- }, children: isPending ? (_jsx(Box, { as: "span", className: "anim-rotate", sx: { display: 'inline-block' }, children: "\u23F3" })) : (_jsx(display.icon, { size: size === 'small' ? 14 : 18 })) }));
158
+ }, children: isPending ? (_jsx(Box, { as: "span", className: "anim-rotate", display: "inline-block", children: "\u23F3" })) : (_jsx(display.icon, { size: size === 'small' ? 14 : 18 })) }));
158
159
  }
159
160
  if (variant === 'compact') {
160
161
  return (_jsx(Button, { ...buttonProps, variant: isConnected ? 'primary' : 'default', leadingVisual: display.icon, trailingVisual: isConnected ? CheckCircleFillIcon : undefined, children: isPending ? 'Connecting...' : display.name }));
161
162
  }
162
163
  // Full variant
163
- return (_jsxs(Box, { sx: {
164
- display: 'flex',
165
- flexDirection: 'column',
166
- gap: 2,
167
- p: 2,
168
- border: '1px solid',
169
- borderColor: isConnected ? 'success.muted' : 'border.default',
170
- borderRadius: 2,
171
- backgroundColor: isConnected ? 'success.subtle' : 'canvas.subtle',
172
- }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Box, { sx: {
173
- width: 40,
174
- height: 40,
175
- borderRadius: 2,
176
- display: 'flex',
177
- alignItems: 'center',
178
- justifyContent: 'center',
179
- backgroundColor: display.color,
180
- color: 'white',
181
- }, children: _jsx(display.icon, { size: 20 }) }), _jsxs(Box, { sx: { flex: 1 }, children: [_jsx(Text, { sx: { fontWeight: 'bold', display: 'block' }, children: display.name }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: isConnected && identity?.userInfo
164
+ return (_jsxs(Box, { display: "flex", flexDirection: "column", gap: 2, p: 2, border: "1px solid", borderColor: isConnected ? 'success.muted' : 'border.default', borderRadius: 2, backgroundColor: isConnected ? 'success.subtle' : 'canvas.subtle', children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, children: [_jsx(Box, { width: 40, height: 40, borderRadius: 2, display: "flex", alignItems: "center", justifyContent: "center", backgroundColor: display.color, color: "white", children: _jsx(display.icon, { size: 20 }) }), _jsxs(Box, { flex: 1, children: [_jsx(Text, { sx: { fontWeight: 'bold', display: 'block' }, children: display.name }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: isConnected && identity?.userInfo
182
165
  ? `Connected as ${identity.userInfo.name || identity.userInfo.email}`
183
- : display.description })] }), !isConnected && (_jsx(Button, { ...buttonProps, variant: "primary", leadingVisual: LinkIcon, children: isPending ? 'Working...' : 'Connect' }))] }), isConnected && identity && (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2, pl: 1 }, children: [identity.userInfo?.avatarUrl && (_jsx("a", { href: identity.userInfo.profileUrl ||
166
+ : display.description })] }), !isConnected && (_jsx(Button, { ...buttonProps, variant: "primary", leadingVisual: LinkIcon, children: isPending ? 'Working...' : 'Connect' }))] }), isConnected && identity && (_jsxs(Box, { display: "flex", flexDirection: "column", gap: 2, children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, pl: 1, children: [identity.userInfo?.avatarUrl && (_jsx("a", { href: identity.userInfo.profileUrl ||
184
167
  `https://github.com/${identity.userInfo.username}`, target: "_blank", rel: "noopener noreferrer", style: { display: 'block', lineHeight: 0 }, children: _jsx("img", { src: identity.userInfo.avatarUrl, alt: identity.userInfo.name || 'User avatar', style: {
185
168
  width: 32,
186
169
  height: 32,
187
170
  borderRadius: '50%',
188
171
  cursor: 'pointer',
189
- } }) })), _jsxs(Box, { sx: { flex: 1 }, children: [identity.userInfo?.username && (_jsx("a", { href: identity.userInfo.profileUrl ||
172
+ } }) })), _jsxs(Box, { flex: 1, children: [identity.userInfo?.username && (_jsx("a", { href: identity.userInfo.profileUrl ||
190
173
  `https://github.com/${identity.userInfo.username}`, target: "_blank", rel: "noopener noreferrer", style: { textDecoration: 'none' }, children: _jsxs(Text, { sx: {
191
174
  fontSize: 1,
192
175
  color: 'fg.muted',
@@ -194,7 +177,7 @@ export const IdentityButton = ({ provider, clientId, providerConfig, scopes, dis
194
177
  ':hover': { textDecoration: 'underline' },
195
178
  }, children: ["@", identity.userInfo.username] }) })), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: identity.token?.expiresAt
196
179
  ? `Expires ${new Date(identity.token.expiresAt).toLocaleDateString()}`
197
- : 'Token does not expire' })] })] }), identity.scopes && identity.scopes.length > 0 && (_jsx(Box, { sx: { display: 'flex', flexWrap: 'wrap', gap: 1, pl: 1 }, children: identity.scopes.map(scope => (_jsx(Text, { sx: {
180
+ : 'Token does not expire' })] })] }), identity.scopes && identity.scopes.length > 0 && (_jsx(Box, { display: "flex", flexWrap: "wrap", gap: 1, pl: 1, children: identity.scopes.map(scope => (_jsx(Text, { sx: {
198
181
  fontSize: 0,
199
182
  px: 2,
200
183
  py: 1,
@@ -220,43 +203,14 @@ export const IdentityConnect = ({ providers, layout = 'list', showHeader = true,
220
203
  onError?.(provider, err);
221
204
  }, [onError]);
222
205
  if (layout === 'inline') {
223
- return (_jsxs(Box, { sx: { display: 'flex', gap: 2, alignItems: 'center' }, children: [showHeader && (_jsxs(Text, { sx: { fontSize: 1, color: 'fg.muted', mr: 2 }, children: [title, ":"] })), providerKeys.map(provider => {
206
+ return (_jsxs(Box, { display: "flex", gap: 2, alignItems: "center", children: [showHeader && (_jsxs(Text, { sx: { fontSize: 1, color: 'fg.muted', mr: 2 }, children: [title, ":"] })), providerKeys.map(provider => {
224
207
  const config = providers[provider];
225
208
  return (_jsx(IdentityButton, { provider: provider, clientId: config.clientId, scopes: config.scopes, providerConfig: config.config, size: size, variant: "icon", disabled: disabled, onConnect: handleConnect, onDisconnect: handleDisconnect, onError: handleError(provider) }, provider));
226
- }), connectedCount > 0 && (_jsxs(Label, { variant: "success", children: [_jsx(Box, { as: "span", sx: {
227
- mr: 1,
228
- display: 'inline-flex',
229
- verticalAlign: 'text-bottom',
230
- }, children: _jsx(CheckCircleFillIcon, { size: 12 }) }), connectedCount, " connected"] }))] }));
209
+ }), connectedCount > 0 && (_jsxs(Label, { variant: "success", children: [_jsx(Box, { as: "span", mr: 1, display: "inline-flex", verticalAlign: "text-bottom", children: _jsx(CheckCircleFillIcon, { size: 12 }) }), connectedCount, " connected"] }))] }));
231
210
  }
232
- return (_jsxs(Box, { sx: {
233
- border: '1px solid',
234
- borderColor: 'border.default',
235
- borderRadius: 2,
236
- backgroundColor: 'canvas.default',
237
- overflow: 'hidden',
238
- }, children: [showHeader && (_jsxs(Box, { sx: {
239
- px: 3,
240
- py: 2,
241
- borderBottom: '1px solid',
242
- borderColor: 'border.default',
243
- backgroundColor: 'canvas.subtle',
244
- display: 'flex',
245
- alignItems: 'center',
246
- justifyContent: 'space-between',
247
- }, children: [_jsx(Text, { sx: { fontWeight: 'bold' }, children: title }), connectedCount > 0 && (_jsxs(Label, { variant: "success", children: [_jsx(Box, { as: "span", sx: {
248
- mr: 1,
249
- display: 'inline-flex',
250
- verticalAlign: 'text-bottom',
251
- }, children: _jsx(CheckCircleFillIcon, { size: 12 }) }), connectedCount, " connected"] }))] })), error && (_jsxs(Flash, { variant: "danger", sx: { m: 2, borderRadius: 1 }, children: [_jsx(Box, { as: "span", sx: { mr: 2, display: 'inline-flex', verticalAlign: 'text-bottom' }, children: _jsx(AlertIcon, { size: 16 }) }), error instanceof Error ? error.message : String(error)] })), _jsx(Box, { sx: {
252
- p: 2,
253
- display: layout === 'grid' ? 'grid' : 'flex',
254
- flexDirection: layout === 'list' ? 'column' : undefined,
255
- gridTemplateColumns: layout === 'grid'
256
- ? 'repeat(auto-fill, minmax(250px, 1fr))'
257
- : undefined,
258
- gap: 2,
259
- }, children: providerKeys.map(provider => {
211
+ return (_jsxs(Box, { border: "1px solid", borderColor: "border.default", borderRadius: 2, backgroundColor: "canvas.default", overflow: "hidden", children: [showHeader && (_jsxs(Box, { px: 3, py: 2, borderBottom: "1px solid", borderColor: "border.default", backgroundColor: "canvas.subtle", display: "flex", alignItems: "center", justifyContent: "space-between", children: [_jsx(Text, { sx: { fontWeight: 'bold' }, children: title }), connectedCount > 0 && (_jsxs(Label, { variant: "success", children: [_jsx(Box, { as: "span", mr: 1, display: "inline-flex", verticalAlign: "text-bottom", children: _jsx(CheckCircleFillIcon, { size: 12 }) }), connectedCount, " connected"] }))] })), error && (_jsxs(Flash, { variant: "danger", sx: { m: 2, borderRadius: 1 }, children: [_jsx(Box, { as: "span", mr: 2, display: "inline-flex", verticalAlign: "text-bottom", children: _jsx(AlertIcon, { size: 16 }) }), error instanceof Error ? error.message : String(error)] })), _jsx(Box, { p: 2, display: layout === 'grid' ? 'grid' : 'flex', flexDirection: layout === 'list' ? 'column' : undefined, gridTemplateColumns: layout === 'grid'
212
+ ? 'repeat(auto-fill, minmax(250px, 1fr))'
213
+ : undefined, gap: 2, children: providerKeys.map(provider => {
260
214
  const config = providers[provider];
261
215
  return (_jsx(IdentityButton, { provider: provider, clientId: config.clientId, scopes: config.scopes, providerConfig: config.config, size: size, variant: showDescriptions ? 'full' : 'compact', disabled: disabled, onConnect: handleConnect, onDisconnect: handleDisconnect, onError: handleError(provider) }, provider));
262
216
  }) })] }));
@@ -310,7 +264,7 @@ export const IdentityMenu = ({ providers, onConnect, onDisconnect, disabled = fa
310
264
  const display = PROVIDER_DISPLAY[provider] || PROVIDER_DISPLAY.custom;
311
265
  const identity = identities.find(id => id.provider === provider);
312
266
  const isConnected = !!identity;
313
- return (_jsxs(ActionList.Item, { onSelect: () => handleProviderClick(provider), disabled: isAuthorizing, children: [_jsx(ActionList.LeadingVisual, { children: _jsx(display.icon, { size: 16 }) }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Text, { children: display.name }), isConnected && (_jsxs(_Fragment, { children: [identity?.userInfo?.avatarUrl && (_jsx(Avatar, { src: identity.userInfo.avatarUrl, size: 16 })), _jsx(Label, { variant: "success", sx: { ml: 1 }, children: "Connected" })] }))] }), _jsx(ActionList.TrailingVisual, { children: isConnected ? (_jsx(UnlinkIcon, { size: 16 })) : (_jsx(LinkIcon, { size: 16 })) })] }, provider));
267
+ return (_jsxs(ActionList.Item, { onSelect: () => handleProviderClick(provider), disabled: isAuthorizing, children: [_jsx(ActionList.LeadingVisual, { children: _jsx(display.icon, { size: 16 }) }), _jsxs(Box, { display: "flex", alignItems: "center", gap: 2, children: [_jsx(Text, { children: display.name }), isConnected && (_jsxs(_Fragment, { children: [identity?.userInfo?.avatarUrl && (_jsx(Avatar, { src: identity.userInfo.avatarUrl, size: 16 })), _jsx(Label, { variant: "success", sx: { ml: 1 }, children: "Connected" })] }))] }), _jsx(ActionList.TrailingVisual, { children: isConnected ? (_jsx(UnlinkIcon, { size: 16 })) : (_jsx(LinkIcon, { size: 16 })) })] }, provider));
314
268
  }) }) }) })] }));
315
269
  };
316
270
  export default IdentityConnect;
@@ -4,7 +4,8 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
4
4
  * Distributed under the terms of the Modified BSD License.
5
5
  */
6
6
  import { useEffect, useState } from 'react';
7
- import { Box, Text, Spinner, Flash, Button } from '@primer/react';
7
+ import { Box } from '@datalayer/primer-addons';
8
+ import { Text, Spinner, Flash, Button } from '@primer/react';
8
9
  import { CheckCircleFillIcon, AlertIcon, XCircleIcon, } from '@primer/octicons-react';
9
10
  import { useIdentityStore } from './identityStore';
10
11
  /**
@@ -155,38 +156,12 @@ export const OAuthCallback = ({ successMessage = 'Account connected successfully
155
156
  window.location.href = redirectUrl;
156
157
  }
157
158
  };
158
- return (_jsx(Box, { sx: {
159
- display: 'flex',
160
- flexDirection: 'column',
161
- alignItems: 'center',
162
- justifyContent: 'center',
163
- minHeight: '100vh',
164
- padding: 4,
165
- backgroundColor: 'canvas.default',
166
- }, children: _jsxs(Box, { sx: {
167
- maxWidth: 400,
168
- width: '100%',
169
- padding: 4,
170
- borderRadius: 2,
171
- border: '1px solid',
172
- borderColor: 'border.default',
173
- backgroundColor: 'canvas.subtle',
174
- textAlign: 'center',
175
- }, children: [status === 'processing' && (_jsxs(_Fragment, { children: [_jsx(Spinner, { size: "large" }), _jsx(Text, { sx: {
159
+ return (_jsx(Box, { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", minHeight: "100vh", padding: 4, backgroundColor: "canvas.default", children: _jsxs(Box, { maxWidth: 400, width: "100%", padding: 4, borderRadius: 2, border: "1px solid", borderColor: "border.default", backgroundColor: "canvas.subtle", textAlign: "center", children: [status === 'processing' && (_jsxs(_Fragment, { children: [_jsx(Spinner, { size: "large" }), _jsx(Text, { sx: {
176
160
  display: 'block',
177
161
  marginTop: 3,
178
162
  fontSize: 2,
179
163
  fontWeight: 'bold',
180
- }, children: "Connecting your account..." }), _jsx(Text, { sx: { display: 'block', marginTop: 2, color: 'fg.muted' }, children: "Please wait while we complete the authorization." })] })), status === 'success' && (_jsxs(_Fragment, { children: [_jsx(Box, { sx: {
181
- width: 64,
182
- height: 64,
183
- borderRadius: '50%',
184
- backgroundColor: 'success.subtle',
185
- display: 'flex',
186
- alignItems: 'center',
187
- justifyContent: 'center',
188
- margin: '0 auto',
189
- }, children: _jsx(Box, { sx: { color: 'success.fg' }, children: _jsx(CheckCircleFillIcon, { size: 32 }) }) }), _jsx(Text, { sx: {
164
+ }, children: "Connecting your account..." }), _jsx(Text, { sx: { display: 'block', marginTop: 2, color: 'fg.muted' }, children: "Please wait while we complete the authorization." })] })), status === 'success' && (_jsxs(_Fragment, { children: [_jsx(Box, { width: 64, height: 64, borderRadius: "50%", backgroundColor: "success.subtle", display: "flex", alignItems: "center", justifyContent: "center", margin: "0 auto", children: _jsx(Box, { color: "success.fg", children: _jsx(CheckCircleFillIcon, { size: 32 }) }) }), _jsx(Text, { sx: {
190
165
  display: 'block',
191
166
  marginTop: 3,
192
167
  fontSize: 2,
@@ -199,25 +174,12 @@ export const OAuthCallback = ({ successMessage = 'Account connected successfully
199
174
  color: 'fg.muted',
200
175
  }, children: isPopup
201
176
  ? 'This window will close automatically...'
202
- : 'Redirecting...' })), showCloseButton && !shouldAutoClose && (_jsx(Button, { variant: "primary", onClick: handleClose, sx: { marginTop: 3 }, children: isPopup ? 'Close' : 'Continue' }))] })), status === 'error' && (_jsxs(_Fragment, { children: [_jsx(Box, { sx: {
203
- width: 64,
204
- height: 64,
205
- borderRadius: '50%',
206
- backgroundColor: 'danger.subtle',
207
- display: 'flex',
208
- alignItems: 'center',
209
- justifyContent: 'center',
210
- margin: '0 auto',
211
- }, children: _jsx(Box, { sx: { color: 'danger.fg' }, children: _jsx(XCircleIcon, { size: 32 }) }) }), _jsx(Text, { sx: {
177
+ : 'Redirecting...' })), showCloseButton && !shouldAutoClose && (_jsx(Button, { variant: "primary", onClick: handleClose, sx: { marginTop: 3 }, children: isPopup ? 'Close' : 'Continue' }))] })), status === 'error' && (_jsxs(_Fragment, { children: [_jsx(Box, { width: 64, height: 64, borderRadius: "50%", backgroundColor: "danger.subtle", display: "flex", alignItems: "center", justifyContent: "center", margin: "0 auto", children: _jsx(Box, { color: "danger.fg", children: _jsx(XCircleIcon, { size: 32 }) }) }), _jsx(Text, { sx: {
212
178
  display: 'block',
213
179
  marginTop: 3,
214
180
  fontSize: 2,
215
181
  fontWeight: 'bold',
216
182
  color: 'danger.fg',
217
- }, children: "Connection Failed" }), _jsxs(Flash, { variant: "danger", sx: { marginTop: 3, textAlign: 'left' }, children: [_jsx(Box, { as: "span", sx: {
218
- mr: 2,
219
- display: 'inline-flex',
220
- verticalAlign: 'text-bottom',
221
- }, children: _jsx(AlertIcon, { size: 16 }) }), errorMessagePrefix, ": ", error] }), showCloseButton && (_jsx(Button, { variant: "danger", onClick: handleClose, sx: { marginTop: 3 }, children: isPopup ? 'Close' : 'Go Back' }))] }))] }) }));
183
+ }, children: "Connection Failed" }), _jsxs(Flash, { variant: "danger", sx: { marginTop: 3, textAlign: 'left' }, children: [_jsx(Box, { as: "span", mr: 2, display: "inline-flex", verticalAlign: "text-bottom", children: _jsx(AlertIcon, { size: 16 }) }), errorMessagePrefix, ": ", error] }), showCloseButton && (_jsx(Button, { variant: "danger", onClick: handleClose, sx: { marginTop: 3 }, children: isPopup ? 'Close' : 'Go Back' }))] }))] }) }));
222
184
  };
223
185
  export default OAuthCallback;
@@ -4,7 +4,7 @@ import { createPortal } from 'react-dom';
4
4
  import { $getSelection, $isRangeSelection, $createParagraphNode, $createTextNode, TextNode, COMMAND_PRIORITY_LOW, createCommand, } from 'lexical';
5
5
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
6
6
  import { autoUpdate, hide, limitShift, offset, shift, size, useFloating, } from '@floating-ui/react-dom';
7
- import { Box } from '@primer/react';
7
+ import { Box } from '@datalayer/primer-addons';
8
8
  import { ChatInline } from '../chat/ChatInline';
9
9
  // Margin from editor edges
10
10
  const MARGIN_X = 32;
@@ -209,18 +209,10 @@ export function ChatInlinePlugin({ protocol, isOpen, onClose, pendingPrompt, onP
209
209
  return null;
210
210
  }
211
211
  const portalTarget = portalContainer || document.body;
212
- return createPortal(_jsx(Box, { ref: setFloating, sx: {
213
- pointerEvents: 'auto',
214
- zIndex: 50,
215
- position: strategy,
216
- top: 0,
217
- left: editor._rootElement
218
- ? editor._rootElement.getBoundingClientRect().left + MARGIN_X
219
- : 0,
220
- transform: `translate3d(0, ${Math.round(y)}px, 0)`,
221
- width: editor._rootElement
222
- ? editor._rootElement.getBoundingClientRect().width - MARGIN_X * 2
223
- : 'auto',
224
- }, children: _jsx(ChatInline, { selectedText: effectiveText, protocol: protocol, onReplaceSelection: handleReplaceSelection, onInsertInline: handleInsertInline, onInsertBelow: handleInsertBelow, onClose: onClose, onSaveSelection: saveSelection, onRestoreSelection: restoreSelection, pendingPrompt: pendingPrompt, onPendingPromptConsumed: onPendingPromptConsumed }) }), portalTarget);
212
+ return createPortal(_jsx(Box, { ref: setFloating, pointerEvents: "auto", zIndex: 50, position: strategy, top: 0, left: editor._rootElement
213
+ ? editor._rootElement.getBoundingClientRect().left + MARGIN_X
214
+ : 0, transform: `translate3d(0, ${Math.round(y)}px, 0)`, width: editor._rootElement
215
+ ? editor._rootElement.getBoundingClientRect().width - MARGIN_X * 2
216
+ : 'auto', children: _jsx(ChatInline, { selectedText: effectiveText, protocol: protocol, onReplaceSelection: handleReplaceSelection, onInsertInline: handleInsertInline, onInsertBelow: handleInsertBelow, onClose: onClose, onSaveSelection: saveSelection, onRestoreSelection: restoreSelection, pendingPrompt: pendingPrompt, onPendingPromptConsumed: onPendingPromptConsumed }) }), portalTarget);
225
217
  }
226
218
  export default ChatInlinePlugin;
@@ -247,9 +247,10 @@ export declare const DATALAYER_BOOTSTRAP_AGENTSPEC = "example-simple";
247
247
  * The application's accent over the theme its conversation wears, in both
248
248
  * modes (LOOP T-05): its bubbles and its one button in its own colour, and
249
249
  * not in the theme's default — the chat sets its theme again inside it, so
250
- * what the page around it set does not reach in. The accents are `loop`'s
251
- * colours: over another theme (T-30) nothing is laid, the theme's own rule.
250
+ * what the page around it set does not reach in. The accents are the theme
251
+ * system's: laid over whatever theme it wears (T-30; decided 2026-10-07).
252
+ * Naming none, it wears the theme's own colours: nothing is laid.
252
253
  */
253
- export declare function appThemeOverrides(app: AppSpec, variant: string): ThemeOverrides | undefined;
254
+ export declare function appThemeOverrides(app: AppSpec): ThemeOverrides | undefined;
254
255
  export declare function AppRenderer({ app, plugins, instance, onPresence, onSaying, paused, sidebar, computer, frame, page, pluginsOff, language, ...embed }: AppRendererProps): React.JSX.Element;
255
256
  export default AppRenderer;
@@ -51,7 +51,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
51
51
  */
52
52
  import { useMemo } from 'react';
53
53
  import { defineExtension, } from '@datalayer/reactor';
54
- import { loopAccentStyles, useSystemColorMode, useThemeStore, } from '@datalayer/primer-addons';
54
+ import { themeAccentVars, useSystemColorMode } from '@datalayer/primer-addons';
55
55
  import { defineAgentCapacityPlugin } from '../plugins/agent-capacity';
56
56
  import { APP_PAGE_SURFACE, defineAppHostPagePlugin, defineAppPagePlugin, hasAppPage, } from '../plugins/app-page';
57
57
  import { CANVAS_BLOCK_PLUGINS, canvasBlocksPluginName, } from '../plugins/canvas-blocks';
@@ -316,15 +316,16 @@ const NO_PLUGINS = [];
316
316
  * The application's accent over the theme its conversation wears, in both
317
317
  * modes (LOOP T-05): its bubbles and its one button in its own colour, and
318
318
  * not in the theme's default — the chat sets its theme again inside it, so
319
- * what the page around it set does not reach in. The accents are `loop`'s
320
- * colours: over another theme (T-30) nothing is laid, the theme's own rule.
319
+ * what the page around it set does not reach in. The accents are the theme
320
+ * system's: laid over whatever theme it wears (T-30; decided 2026-10-07).
321
+ * Naming none, it wears the theme's own colours: nothing is laid.
321
322
  */
322
- export function appThemeOverrides(app, variant) {
323
+ export function appThemeOverrides(app) {
323
324
  const accent = app.interface?.accent;
324
- return accent && variant === 'loop'
325
+ return accent
325
326
  ? {
326
- light: loopAccentStyles(accent, 'light'),
327
- dark: loopAccentStyles(accent, 'dark'),
327
+ light: themeAccentVars(accent, 'light'),
328
+ dark: themeAccentVars(accent, 'dark'),
328
329
  }
329
330
  : undefined;
330
331
  }
@@ -406,21 +407,19 @@ export function AppRenderer({ app, plugins = NO_PLUGINS, instance, onPresence, o
406
407
  /*
407
408
  * The theme it runs in (T-30): the one its host says, else the one its
408
409
  * Appspec names, else the page's — the person's own. Its mode likewise;
409
- * `auto` is the device's.
410
+ * `auto` is the device's. Its accent is laid over whichever it is.
410
411
  */
411
- const pageTheme = useThemeStore(state => state.theme);
412
412
  const system = useSystemColorMode();
413
413
  const named = app.interface?.theme;
414
- const worn = embed.themeVariant ?? named?.variant ?? pageTheme;
415
414
  const namedMode = named?.mode === 'auto'
416
415
  ? system
417
416
  : named?.mode === 'light' || named?.mode === 'dark'
418
417
  ? named.mode
419
418
  : undefined;
420
419
  const accent = app.interface?.accent;
421
- const themeOverrides = useMemo(() => appThemeOverrides(app, worn),
420
+ const themeOverrides = useMemo(() => appThemeOverrides(app),
422
421
  // eslint-disable-next-line react-hooks/exhaustive-deps
423
- [accent, worn]);
422
+ [accent]);
424
423
  if ('problem' in preset) {
425
424
  return (_jsx("div", { role: "status", style: { padding: 16 }, children: preset.problem }));
426
425
  }
@@ -122,7 +122,6 @@ export function emptyAppspec(kind = 'chat') {
122
122
  },
123
123
  interface: {
124
124
  layout: DEFAULT_LAYOUTS[kind],
125
- accent: 'green',
126
125
  welcome: '',
127
126
  starters: [],
128
127
  commands: [],
@@ -463,7 +462,11 @@ function dumpPage(page) {
463
462
  function parseInterface(data, kind) {
464
463
  const parsed = {
465
464
  layout: oneOf(data.layout, ['chat', 'page', 'split'], DEFAULT_LAYOUTS[kind]),
466
- accent: oneOf(data.accent, APP_ACCENTS, 'green'),
465
+ // Unsaid, the theme's own colours: no accent is assumed. A name that is
466
+ // not one of the six is refused by `checkAppspec`.
467
+ accent: APP_ACCENTS.includes(data.accent)
468
+ ? data.accent
469
+ : undefined,
467
470
  welcome: text(data.welcome),
468
471
  starters: records(data.starters).map(parseStarter),
469
472
  commands: records(data.commands).map(parseCommand),
@@ -814,7 +817,7 @@ function dumpInterface(spec, kind) {
814
817
  const writer = new Writer()
815
818
  // A layout is written when it is not the one its kind starts with.
816
819
  .value('layout', spec.layout, DEFAULT_LAYOUTS[kind])
817
- .value('accent', spec.accent, 'green')
820
+ .value('accent', spec.accent, undefined)
818
821
  .text('welcome', spec.welcome)
819
822
  .list('starters', spec.starters.map(dumpStarter))
820
823
  .list('commands', spec.commands.map(command => ({
@@ -171,7 +171,7 @@ export type AppFloatingProps = {
171
171
  export declare function AppFloating({ app, view, colorMode, themeVariant, themeOverrides, character, serverUrl, instance, embedToken, renderer, host, session, language, }: AppFloatingProps): JSX.Element;
172
172
  /** The application's theme (`loop` unless it names one), with its (or the host's) accent and face. */
173
173
  export declare function EmbedThemed({ accent, colorMode, font, variant, children, style, }: {
174
- accent: AppAccent;
174
+ accent?: AppAccent;
175
175
  colorMode: 'light' | 'dark';
176
176
  font?: string;
177
177
  variant: AppThemeVariant;
@@ -29,7 +29,8 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
29
29
  * it does inline; the chrome told by the workspace what it is doing and
30
30
  * what it last said, for the balloon and the blink.
31
31
  *
32
- * In the `loop` theme with the application's accent (T-12, T-05), which the
32
+ * In its theme (`loop` unless it names one) with the application's accent
33
+ * over it, whichever theme (T-12, T-05), which the
33
34
  * host may override with the face and the mode (D-11) — around the
34
35
  * conversation and inside it, where the chat sets its theme again.
35
36
  *
@@ -143,12 +143,6 @@ export function LoopEmbed({ agentId = '', showHeader = false, chatHeaderActions,
143
143
  return (_jsx(QueryClientProvider, { client: internalQueryClient, children: frameTitle !== undefined ? (_jsx(WindowFrame, { title: frameTitle, height: frameHeight, children: shell })) : (
144
144
  // Filling its host, whatever the host is: in a flex row it used to
145
145
  // shrink to the chat's own width and leave the rest of the frame bare.
146
- _jsx(Box, { sx: {
147
- height: '100%',
148
- minHeight: 0,
149
- width: '100%',
150
- flex: '1 1 auto',
151
- minWidth: 0,
152
- }, children: shell })) }));
146
+ _jsx(Box, { height: "100%", minHeight: 0, width: "100%", flex: "1 1 auto", minWidth: 0, children: shell })) }));
153
147
  }
154
148
  export default LoopEmbed;
@@ -27,7 +27,7 @@ export declare const EMBED_ATTRIBUTES: {
27
27
  readonly token: "An embed token for an application that is not public, issued to your server for each visit.";
28
28
  readonly spec: "The address of an Appspec (YAML or JSON) to run, in place of `app`.";
29
29
  readonly mode: "inline, bubble, panel or assistant; the Appspec’s `deployment.embedded.mode` by default, then inline.";
30
- readonly accent: "green, rose, sky, lime, sun or violet; the Appspec’s `interface.accent` by default.";
30
+ readonly accent: "green, rose, sky, lime, sun or violet; the Appspec’s `interface.accent` by default, else the theme’s own colours.";
31
31
  readonly theme: "light, dark or auto (the visitor’s system); auto by default.";
32
32
  readonly font: "A CSS font family for the application’s text; Inter, then the system’s sans-serif, by default.";
33
33
  readonly server: "An agent-runtimes server the application’s agent runs on; a Datalayer runtime by default.";
@@ -84,8 +84,8 @@ export type EmbedInputs = {
84
84
  /** How an application is shown and dressed in a host's page. */
85
85
  export type EmbedLook = {
86
86
  mode: AppEmbedMode;
87
- /** The accent the host chose, or the application's own. */
88
- accent: AppAccent;
87
+ /** The accent the host chose, or the application's own; none: the theme's own colours. */
88
+ accent?: AppAccent;
89
89
  colorMode: EmbedColorMode;
90
90
  /** The host's face; empty for the theme's own. */
91
91
  font: string;
@@ -19,7 +19,7 @@ export const EMBED_ATTRIBUTES = {
19
19
  token: 'An embed token for an application that is not public, issued to your server for each visit.',
20
20
  spec: 'The address of an Appspec (YAML or JSON) to run, in place of `app`.',
21
21
  mode: 'inline, bubble, panel or assistant; the Appspec’s `deployment.embedded.mode` by default, then inline.',
22
- accent: 'green, rose, sky, lime, sun or violet; the Appspec’s `interface.accent` by default.',
22
+ accent: 'green, rose, sky, lime, sun or violet; the Appspec’s `interface.accent` by default, else the theme’s own colours.',
23
23
  theme: 'light, dark or auto (the visitor’s system); auto by default.',
24
24
  font: 'A CSS font family for the application’s text; Inter, then the system’s sans-serif, by default.',
25
25
  server: 'An agent-runtimes server the application’s agent runs on; a Datalayer runtime by default.',
@@ -105,8 +105,7 @@ export function embedLookOf(inputs, app) {
105
105
  'inline';
106
106
  const accent = oneOf(attributes.accent, APP_ACCENTS, 'an accent') ??
107
107
  oneOf(variables.accent, APP_ACCENTS, 'an accent') ??
108
- app?.interface?.accent ??
109
- 'green';
108
+ app?.interface?.accent;
110
109
  const colorMode = oneOf(attributes.theme, EMBED_COLOR_MODES, 'a theme') ??
111
110
  oneOf(variables.theme, EMBED_COLOR_MODES, 'a theme') ??
112
111
  app?.interface?.theme?.mode ??
@@ -3,11 +3,11 @@ import type { AppAccent, AppThemeVariant } from '../../types/agentspecs';
3
3
  import type { ThemeOverrides } from '../../types/chat';
4
4
  /**
5
5
  * The theme as the embed wears it — `loop`, or the one the application
6
- * names (T-30) — with the application's accent over `loop` in both modes
6
+ * names (T-30) — with the application's accent over it in both modes
7
7
  * (T-05), and the host's face when it named one.
8
8
  */
9
9
  export declare function embedThemeStyles({ accent, font, variant, }: {
10
- accent: AppAccent;
10
+ accent?: AppAccent;
11
11
  font?: string;
12
12
  variant?: AppThemeVariant;
13
13
  }): ThemeStyles;
@@ -15,11 +15,11 @@ export declare function embedThemeStyles({ accent, font, variant, }: {
15
15
  * The same accent and face laid over the conversation's own theme (T-05,
16
16
  * D-11): the chat sets its theme again inside it, which would put the
17
17
  * theme's colours and face back over what the embed set around it. The
18
- * accent's properties in each mode (over `loop` only), and, when the host
18
+ * accent's properties in each mode (over any theme), and, when the host
19
19
  * named a face, every property of the theme that names its own.
20
20
  */
21
21
  export declare function embedThemeOverrides({ accent, font, variant, }: {
22
- accent: AppAccent;
22
+ accent?: AppAccent;
23
23
  font?: string;
24
24
  variant?: AppThemeVariant;
25
25
  }): ThemeOverrides;
@@ -2,7 +2,7 @@
2
2
  * Copyright (c) 2025-2026 Datalayer, Inc.
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
- import { getThemeConfig, loopAccentStyles, loopFontFamily, scopeThemeCss, THEME_SCOPE_ATTRIBUTE, } from '@datalayer/primer-addons';
5
+ import { getThemeConfig, loopFontFamily, scopeThemeCss, THEME_SCOPE_ATTRIBUTE, themeAccentVars, } from '@datalayer/primer-addons';
6
6
  /** One mode's properties, with the theme's face replaced by the host's. */
7
7
  function withFace(styles, font, own) {
8
8
  if (!font || !own) {
@@ -20,18 +20,22 @@ function faceOf(variant, styles) {
20
20
  }
21
21
  return typeof styles.fontFamily === 'string' ? styles.fontFamily : '';
22
22
  }
23
- /** The accent over a theme: `loop`'s colours, over `loop` only (T-30). */
24
- const accentOver = (variant, accent, which) => variant === 'loop' ? loopAccentStyles(accent, which) : {};
23
+ /**
24
+ * The accent over a theme, whichever theme (T-05, T-30; every theme since
25
+ * 2026-10-07); none when neither the application nor the host names one —
26
+ * the theme's own colours.
27
+ */
28
+ const accentOver = (accent, which) => (accent ? themeAccentVars(accent, which) : {});
25
29
  /**
26
30
  * The theme as the embed wears it — `loop`, or the one the application
27
- * names (T-30) — with the application's accent over `loop` in both modes
31
+ * names (T-30) — with the application's accent over it in both modes
28
32
  * (T-05), and the host's face when it named one.
29
33
  */
30
34
  export function embedThemeStyles({ accent, font = '', variant = 'loop', }) {
31
35
  const base = getThemeConfig(variant).themeStyles;
32
36
  const mode = (which) => {
33
37
  const theme = base[which];
34
- return withFace({ ...theme, ...accentOver(variant, accent, which) }, font, faceOf(variant, theme));
38
+ return withFace({ ...theme, ...accentOver(accent, which) }, font, faceOf(variant, theme));
35
39
  };
36
40
  return {
37
41
  ...base,
@@ -43,7 +47,7 @@ export function embedThemeStyles({ accent, font = '', variant = 'loop', }) {
43
47
  * The same accent and face laid over the conversation's own theme (T-05,
44
48
  * D-11): the chat sets its theme again inside it, which would put the
45
49
  * theme's colours and face back over what the embed set around it. The
46
- * accent's properties in each mode (over `loop` only), and, when the host
50
+ * accent's properties in each mode (over any theme), and, when the host
47
51
  * named a face, every property of the theme that names its own.
48
52
  */
49
53
  export function embedThemeOverrides({ accent, font = '', variant = 'loop', }) {
@@ -51,7 +55,7 @@ export function embedThemeOverrides({ accent, font = '', variant = 'loop', }) {
51
55
  const mode = (which) => {
52
56
  const theme = base[which];
53
57
  const faced = Object.fromEntries(Object.entries(withFace(theme, font, faceOf(variant, theme))).filter(([name, value]) => typeof value === 'string' && value !== theme[name]));
54
- return { ...faced, ...accentOver(variant, accent, which) };
58
+ return { ...faced, ...accentOver(accent, which) };
55
59
  };
56
60
  return { light: mode('light'), dark: mode('dark') };
57
61
  }
@@ -100,14 +100,14 @@ const STATUS_LABEL = {
100
100
  function StatusBadge({ status, }) {
101
101
  switch (status) {
102
102
  case 'done':
103
- return (_jsx(Box, { sx: { color: 'success.fg', display: 'flex' }, children: _jsx(CheckCircleIcon, {}) }));
103
+ return (_jsx(Box, { color: "success.fg", display: "flex", children: _jsx(CheckCircleIcon, {}) }));
104
104
  case 'stopped':
105
- return (_jsx(Box, { sx: { color: 'attention.fg', display: 'flex' }, children: _jsx(AlertIcon, {}) }));
105
+ return (_jsx(Box, { color: "attention.fg", display: "flex", children: _jsx(AlertIcon, {}) }));
106
106
  case 'failed':
107
- return (_jsx(Box, { sx: { color: 'danger.fg', display: 'flex' }, children: _jsx(AlertIcon, {}) }));
107
+ return (_jsx(Box, { color: "danger.fg", display: "flex", children: _jsx(AlertIcon, {}) }));
108
108
  case 'launching':
109
109
  case 'working':
110
- return (_jsx(Box, { sx: { color: 'accent.fg', display: 'flex' }, children: _jsx(DependabotIcon, {}) }));
110
+ return (_jsx(Box, { color: "accent.fg", display: "flex", children: _jsx(DependabotIcon, {}) }));
111
111
  default:
112
112
  return _jsx(BroadcastIcon, {});
113
113
  }
@@ -120,13 +120,7 @@ function LaunchChip({ launch, }) {
120
120
  : launch === 'local'
121
121
  ? DeviceDesktopIcon
122
122
  : BroadcastIcon;
123
- return (_jsxs(Box, { sx: {
124
- display: 'inline-flex',
125
- alignItems: 'center',
126
- gap: 1,
127
- fontSize: 0,
128
- color: 'fg.muted',
129
- }, children: [_jsx(Icon, { size: 12 }), _jsx(Text, { sx: { fontSize: 0 }, children: launch })] }));
123
+ return (_jsxs(Box, { display: "inline-flex", alignItems: "center", gap: 1, fontSize: 0, color: "fg.muted", children: [_jsx(Icon, { size: 12 }), _jsx(Text, { sx: { fontSize: 0 }, children: launch })] }));
130
124
  }
131
125
  function SectionHeading({ children }) {
132
126
  return (_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: children }));
@@ -142,30 +136,9 @@ export function A2ASidebar(_props) {
142
136
  const [shown, setShown] = useState(null);
143
137
  const activeOverA2A = activeKey !== null &&
144
138
  (activity[activeKey] ?? []).some(event => event.transport === 'a2a');
145
- return (_jsxs(Box, { "data-a2a-sidebar": true, sx: { display: 'flex', flexDirection: 'column', gap: 4 }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(BroadcastIcon, { size: 16 }), _jsx(Heading, { as: "h3", sx: { fontSize: 2, m: 0, flex: 1 }, children: "A2A agents" }), _jsx(Label, { variant: "accent", children: agents.length })] }), _jsxs(Box, { children: [_jsx(SectionHeading, { children: "Running now" }), activeKey && activeOverA2A ? (_jsx(SubagentChatPanel, { toolCallId: activeKey, height: A2A_ACTIVE_PANEL_HEIGHT })) : (_jsx(Box, { "data-a2a-sidebar-idle": true, sx: {
146
- height: A2A_ACTIVE_PANEL_HEIGHT,
147
- display: 'flex',
148
- alignItems: 'center',
149
- justifyContent: 'center',
150
- border: '1px solid',
151
- borderColor: 'border.muted',
152
- borderRadius: 2,
153
- bg: 'canvas.default',
154
- }, children: _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', m: 0 }, children: "No A2A agent running" }) }))] }), _jsxs(Box, { children: [_jsx(SectionHeading, { children: "Remote agents" }), agents.length === 0 ? (_jsx(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', m: 0 }, children: "This agent declares no A2A agents." })) : (_jsx(Timeline, { children: agents.map(agent => {
139
+ return (_jsxs(Box, { "data-a2a-sidebar": true, display: "flex", flexDirection: "column", gap: 4, children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, children: [_jsx(BroadcastIcon, { size: 16 }), _jsx(Heading, { as: "h3", sx: { fontSize: 2, m: 0, flex: 1 }, children: "A2A agents" }), _jsx(Label, { variant: "accent", children: agents.length })] }), _jsxs(Box, { children: [_jsx(SectionHeading, { children: "Running now" }), activeKey && activeOverA2A ? (_jsx(SubagentChatPanel, { toolCallId: activeKey, height: A2A_ACTIVE_PANEL_HEIGHT })) : (_jsx(Box, { "data-a2a-sidebar-idle": true, height: A2A_ACTIVE_PANEL_HEIGHT, display: "flex", alignItems: "center", justifyContent: "center", border: "1px solid", borderColor: "border.muted", borderRadius: 2, bg: "canvas.default", children: _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', m: 0 }, children: "No A2A agent running" }) }))] }), _jsxs(Box, { children: [_jsx(SectionHeading, { children: "Remote agents" }), agents.length === 0 ? (_jsx(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', m: 0 }, children: "This agent declares no A2A agents." })) : (_jsx(Timeline, { children: agents.map(agent => {
155
140
  const status = STATUS_LABEL[agent.status];
156
- return (_jsxs(Timeline.Item, { "data-a2a-agent": agent.name, children: [_jsx(Timeline.Badge, { children: _jsx(StatusBadge, { status: agent.status }) }), _jsxs(Timeline.Body, { children: [_jsxs(Box, { sx: {
157
- display: 'flex',
158
- alignItems: 'center',
159
- gap: 2,
160
- mb: 1,
161
- flexWrap: 'wrap',
162
- }, children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1 }, children: agent.name }), _jsx(Label, { variant: status.variant, size: "small", children: status.text }), _jsx(LaunchChip, { launch: agent.launch })] }), agent.description ? (_jsx(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', mt: 0, mb: 1 }, children: agent.description })) : null, _jsxs(Box, { sx: {
163
- display: 'flex',
164
- flexDirection: 'column',
165
- gap: '2px',
166
- fontSize: 0,
167
- color: 'fg.muted',
168
- }, children: [agent.card?.name ? (_jsxs(Text, { sx: { fontSize: 0 }, children: ["Card: ", agent.card.name, agent.card.version ? ` v${agent.card.version}` : ''] })) : agent.ref ? (_jsx(Text, { sx: { fontSize: 0, fontFamily: 'mono' }, children: agent.ref })) : null, agent.url ? (_jsx(Link, { as: "button", type: "button", "data-a2a-card-button": agent.name, onClick: () => setShown(agent), sx: {
141
+ return (_jsxs(Timeline.Item, { "data-a2a-agent": agent.name, children: [_jsx(Timeline.Badge, { children: _jsx(StatusBadge, { status: agent.status }) }), _jsxs(Timeline.Body, { children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, mb: 1, flexWrap: "wrap", children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1 }, children: agent.name }), _jsx(Label, { variant: status.variant, size: "small", children: status.text }), _jsx(LaunchChip, { launch: agent.launch })] }), agent.description ? (_jsx(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', mt: 0, mb: 1 }, children: agent.description })) : null, _jsxs(Box, { display: "flex", flexDirection: "column", gap: "2px", fontSize: 0, color: "fg.muted", children: [agent.card?.name ? (_jsxs(Text, { sx: { fontSize: 0 }, children: ["Card: ", agent.card.name, agent.card.version ? ` v${agent.card.version}` : ''] })) : agent.ref ? (_jsx(Text, { sx: { fontSize: 0, fontFamily: 'mono' }, children: agent.ref })) : null, agent.url ? (_jsx(Link, { as: "button", type: "button", "data-a2a-card-button": agent.name, onClick: () => setShown(agent), sx: {
169
142
  fontSize: 0,
170
143
  fontFamily: 'mono',
171
144
  overflow: 'hidden',