zidane-ui 9.1.13 → 9.1.16

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 (290) hide show
  1. package/dist/adapters/index.d.ts +2 -2
  2. package/dist/adapters/index.js +2 -2
  3. package/dist/adapters/live.d.ts +29 -3
  4. package/dist/adapters/live.js +9 -1
  5. package/dist/adapters/server-composer-host.js +17 -2
  6. package/dist/adapters/server-extensions-host.d.ts +0 -1
  7. package/dist/adapters/server-extensions-host.js +4 -15
  8. package/dist/adapters/server-git-host.js +7 -16
  9. package/dist/adapters/server-host.js +181 -43
  10. package/dist/adapters/server-machines-host.d.ts +2 -0
  11. package/dist/adapters/server-machines-host.js +22 -23
  12. package/dist/adapters/server-onboarding-host.d.ts +1 -1
  13. package/dist/adapters/server-onboarding-host.js +3 -4
  14. package/dist/adapters/server-session-host.js +22 -3
  15. package/dist/adapters/server-settings-accounts.js +2 -2
  16. package/dist/adapters/server-settings-host.js +2 -2
  17. package/dist/adapters/server-settings-performance.js +7 -9
  18. package/dist/adapters/server-settings-sections.js +13 -14
  19. package/dist/adapters/server-sidebar-host.js +2 -2
  20. package/dist/adapters/sse-host.js +68 -3
  21. package/dist/adapters/sse-protocol.d.ts +12 -2
  22. package/dist/adapters/sse-protocol.js +4 -2
  23. package/dist/app/AppHostProvider.js +4 -3
  24. package/dist/app/ModalProvider.d.ts +13 -3
  25. package/dist/app/ModalProvider.js +103 -24
  26. package/dist/app/NoticeStack.d.ts +33 -0
  27. package/dist/app/NoticeStack.js +90 -0
  28. package/dist/app/index.d.ts +3 -2
  29. package/dist/app/index.js +3 -2
  30. package/dist/chat/SessionFilterMenu.d.ts +1 -1
  31. package/dist/chat/SessionFilterMenu.js +2 -1
  32. package/dist/chat/composer/Composer.js +10 -8
  33. package/dist/chat/composer/ModelChainList.js +17 -8
  34. package/dist/chat/composer/ModelChainTooltip.js +5 -2
  35. package/dist/chat/composer/use-draft-target.d.ts +20 -1
  36. package/dist/chat/composer/use-draft-target.js +121 -5
  37. package/dist/chat/composer/use-new-session-defaults.d.ts +5 -1
  38. package/dist/chat/composer/use-new-session-defaults.js +17 -4
  39. package/dist/chat/headless/chip-labels.d.ts +1 -0
  40. package/dist/chat/headless/chip-labels.js +1 -0
  41. package/dist/chat/headless/composer/labels-editor.d.ts +0 -2
  42. package/dist/chat/headless/composer/labels-editor.js +0 -2
  43. package/dist/chat/headless/draft-target.d.ts +21 -1
  44. package/dist/chat/headless/fixture-host.js +17 -2
  45. package/dist/chat/headless/host.d.ts +3 -3
  46. package/dist/chat/headless/index.d.ts +9 -9
  47. package/dist/chat/headless/index.js +2 -2
  48. package/dist/chat/headless/labels.d.ts +13 -6
  49. package/dist/chat/headless/labels.js +10 -9
  50. package/dist/chat/headless/session-list.d.ts +20 -8
  51. package/dist/chat/headless/session-list.js +1 -0
  52. package/dist/chat/headless/sidebar/directory.d.ts +56 -14
  53. package/dist/chat/headless/sidebar/directory.js +149 -70
  54. package/dist/chat/headless/sidebar/index.d.ts +3 -3
  55. package/dist/chat/headless/sidebar/index.js +2 -2
  56. package/dist/chat/headless/sidebar/labels.d.ts +15 -8
  57. package/dist/chat/headless/sidebar/types.d.ts +3 -1
  58. package/dist/chat/headless/sidebar/view.d.ts +13 -5
  59. package/dist/chat/headless/sidebar/view.js +31 -11
  60. package/dist/chat/headless/streams/actions.d.ts +5 -3
  61. package/dist/chat/headless/streams/actions.js +3 -2
  62. package/dist/chat/headless/streams/index.d.ts +3 -3
  63. package/dist/chat/headless/streams/merge.d.ts +6 -10
  64. package/dist/chat/headless/streams/merge.js +7 -21
  65. package/dist/chat/headless/streams/session-streams.d.ts +29 -4
  66. package/dist/chat/headless/streams/session-streams.js +86 -0
  67. package/dist/chat/headless/streams/store.d.ts +162 -16
  68. package/dist/chat/headless/streams/store.js +334 -38
  69. package/dist/chat/headless/streams/types.d.ts +10 -7
  70. package/dist/chat/headless/transcript-labels.d.ts +1 -0
  71. package/dist/chat/interactions/PlanCard.js +10 -3
  72. package/dist/chat/interactions/QuestionForm.js +7 -3
  73. package/dist/chat/interactions/card-ui.d.ts +5 -3
  74. package/dist/chat/interactions/card-ui.js +9 -7
  75. package/dist/chat/rich-composer/RichComposer.js +1 -7
  76. package/dist/chat/rich-composer/composer-extensions.d.ts +0 -2
  77. package/dist/chat/rich-composer/composer-extensions.js +2 -2
  78. package/dist/chat/rich-composer/use-composer-editor.d.ts +0 -2
  79. package/dist/chat/rich-composer/use-composer-editor.js +1 -2
  80. package/dist/chat/sidebar/SessionSidebar.js +5 -5
  81. package/dist/chat/sidebar/SidebarFilterMenu.js +3 -1
  82. package/dist/chat/sidebar/SidebarFrame.d.ts +4 -0
  83. package/dist/chat/sidebar/SidebarFrame.js +27 -9
  84. package/dist/chat/sidebar/SidebarGroupHeader.js +1 -1
  85. package/dist/chat/sidebar/SidebarHostProvider.d.ts +8 -5
  86. package/dist/chat/sidebar/SidebarHostProvider.js +13 -9
  87. package/dist/chat/sidebar/SidebarToggleButton.js +7 -3
  88. package/dist/chat/sidebar/index.d.ts +2 -2
  89. package/dist/chat/sidebar/session-menu.js +4 -4
  90. package/dist/chat/sidebar/useSaveViewAsSpace.js +2 -2
  91. package/dist/chat/testing/contract.js +2 -2
  92. package/dist/chat/transcript/AuthFailureCard.js +11 -8
  93. package/dist/chat/transcript/BadgeMenu.js +13 -2
  94. package/dist/chat/transcript/MermaidDiagram.js +7 -3
  95. package/dist/chat/transcript/fold.d.ts +4 -0
  96. package/dist/chat/transcript/fold.js +53 -22
  97. package/dist/chat/transcript/script-input.d.ts +1 -1
  98. package/dist/chat/transcript/shell-block.js +7 -3
  99. package/dist/chat/transcript/useStickToBottom.js +12 -0
  100. package/dist/components/BrowserSignIn.js +23 -21
  101. package/dist/components/Form.d.ts +6 -4
  102. package/dist/components/Form.js +16 -8
  103. package/dist/components/LoadError.d.ts +4 -2
  104. package/dist/components/LoadError.js +13 -9
  105. package/dist/components/Notice.d.ts +29 -0
  106. package/dist/components/Notice.js +63 -0
  107. package/dist/components/PanelEmpty.d.ts +1 -1
  108. package/dist/components/PanelEmpty.js +4 -2
  109. package/dist/components/Restricted.d.ts +1 -1
  110. package/dist/components/palette/PaletteList.js +8 -1
  111. package/dist/components/palette/PalettePanel.js +14 -6
  112. package/dist/core.css +24 -5
  113. package/dist/dist/{index-Bq87OcGy.d.ts → index-BZM8tu4L.d.ts} +28 -3
  114. package/dist/dist/index.d.ts +2 -2
  115. package/dist/dist/{timeout-B5pO5I5a.d.ts → timeout-Cyx3VGPz.d.ts} +1 -1
  116. package/dist/extensions/ExtensionSettingsPage.js +1 -4
  117. package/dist/extensions/ExtensionSettingsSection.js +4 -3
  118. package/dist/extensions/ExtensionSettingsSidebar.js +2 -6
  119. package/dist/extensions/SettingsWireForm.d.ts +1 -7
  120. package/dist/extensions/SettingsWireForm.js +7 -5
  121. package/dist/extensions/headless/fixture-host.d.ts +1 -5
  122. package/dist/extensions/headless/fixture-host.js +1 -4
  123. package/dist/extensions/headless/host.d.ts +1 -11
  124. package/dist/extensions/headless/index.d.ts +3 -3
  125. package/dist/extensions/headless/index.js +2 -2
  126. package/dist/extensions/headless/select.d.ts +1 -11
  127. package/dist/extensions/headless/select.js +1 -18
  128. package/dist/files/EditorColumn.js +12 -1
  129. package/dist/files/TreeColumn.js +13 -20
  130. package/dist/files/useOpenFiles.js +2 -0
  131. package/dist/git/BranchMenu.js +5 -3
  132. package/dist/git/ImportRepoDialog.js +18 -9
  133. package/dist/git/MoveSessionDialog.js +15 -7
  134. package/dist/git/RemoteFolderPicker.js +34 -16
  135. package/dist/git/SyncChip.js +17 -17
  136. package/dist/git/WherePicker.d.ts +16 -1
  137. package/dist/git/WherePicker.js +80 -36
  138. package/dist/git/headless/environment.d.ts +33 -3
  139. package/dist/git/headless/environment.js +33 -5
  140. package/dist/git/headless/index.d.ts +2 -2
  141. package/dist/git/headless/index.js +2 -2
  142. package/dist/git/headless/labels.d.ts +15 -2
  143. package/dist/git/headless/labels.js +17 -4
  144. package/dist/git/useEnvironmentChoices.d.ts +3 -1
  145. package/dist/git/useEnvironmentChoices.js +6 -3
  146. package/dist/index.d.ts +2 -1
  147. package/dist/index.js +2 -1
  148. package/dist/labels.d.ts +5 -0
  149. package/dist/labels.js +5 -0
  150. package/dist/machines/AddMachineDialog.d.ts +34 -0
  151. package/dist/machines/AddMachineDialog.js +464 -0
  152. package/dist/machines/Banners.d.ts +33 -4
  153. package/dist/machines/Banners.js +64 -3
  154. package/dist/machines/DaemonMenu.js +27 -4
  155. package/dist/machines/HostCapabilities.d.ts +1 -3
  156. package/dist/machines/HostCapabilities.js +24 -45
  157. package/dist/machines/HostSyncPanel.js +123 -129
  158. package/dist/machines/HostsSection.d.ts +4 -1
  159. package/dist/machines/HostsSection.js +30 -7
  160. package/dist/machines/MachinesExplainer.d.ts +17 -0
  161. package/dist/machines/MachinesExplainer.js +71 -0
  162. package/dist/machines/MachinesProvider.d.ts +14 -2
  163. package/dist/machines/MachinesProvider.js +35 -1
  164. package/dist/machines/ServerAddedCard.d.ts +31 -0
  165. package/dist/machines/ServerAddedCard.js +72 -0
  166. package/dist/machines/ServerCard.js +91 -215
  167. package/dist/machines/ServerMachinesPanel.d.ts +2 -2
  168. package/dist/machines/ServerMachinesPanel.js +184 -323
  169. package/dist/machines/ServerUpdatePanel.js +51 -40
  170. package/dist/machines/ShareThisComputerForm.d.ts +19 -0
  171. package/dist/machines/ShareThisComputerForm.js +133 -0
  172. package/dist/machines/TokensPanel.d.ts +5 -3
  173. package/dist/machines/TokensPanel.js +98 -78
  174. package/dist/machines/headless/fixture-host.d.ts +19 -3
  175. package/dist/machines/headless/fixture-host.js +42 -5
  176. package/dist/machines/headless/fixtures.js +4 -6
  177. package/dist/machines/headless/host.d.ts +40 -19
  178. package/dist/machines/headless/index.d.ts +3 -3
  179. package/dist/machines/headless/index.js +2 -2
  180. package/dist/machines/headless/labels.d.ts +63 -20
  181. package/dist/machines/headless/labels.js +88 -25
  182. package/dist/machines/headless/messages.js +8 -0
  183. package/dist/machines/headless/stores.d.ts +9 -2
  184. package/dist/machines/headless/stores.js +28 -1
  185. package/dist/machines/index.d.ts +7 -3
  186. package/dist/machines/index.js +8 -4
  187. package/dist/machines/testing/contract.d.ts +15 -3
  188. package/dist/machines/testing/contract.js +68 -14
  189. package/dist/motion/grow.d.ts +8 -1
  190. package/dist/motion/grow.js +10 -4
  191. package/dist/onboarding/demos/index.js +1 -1
  192. package/dist/onboarding/headless/labels.d.ts +13 -0
  193. package/dist/onboarding/headless/labels.js +8 -0
  194. package/dist/onboarding/index.js +3 -3
  195. package/dist/onboarding/sources/SourceBrowser.js +11 -7
  196. package/dist/onboarding/steps/ConnectorsStep.js +1 -1
  197. package/dist/onboarding/steps/ImportStep.js +4 -1
  198. package/dist/onboarding/steps/ReadyStep.js +9 -2
  199. package/dist/onboarding/steps/SkillsStep.js +1 -1
  200. package/dist/onboarding/steps/connect/KeyForm.js +6 -2
  201. package/dist/onboarding/steps/connect/ProviderPanel.js +6 -2
  202. package/dist/onboarding/steps/connect/ProviderReady.js +25 -20
  203. package/dist/onboarding/steps/tasks.js +17 -14
  204. package/dist/server/sse-handler.js +141 -19
  205. package/dist/session/ArtifactsPanel.js +39 -17
  206. package/dist/session/PlanTracker.js +12 -7
  207. package/dist/session/ProjectHome.js +13 -11
  208. package/dist/session/RemindersPanel.js +34 -16
  209. package/dist/session/RunningWorkDialog.js +6 -2
  210. package/dist/session/SecretsPanel.js +29 -10
  211. package/dist/session/SessionDetailsDialog.d.ts +1 -1
  212. package/dist/session/SessionDetailsDialog.js +18 -10
  213. package/dist/session/SideChat.js +10 -7
  214. package/dist/session/TurnDetailsDialog.js +19 -5
  215. package/dist/session/UsagePanel.js +10 -4
  216. package/dist/session/headless/host.d.ts +2 -0
  217. package/dist/session/headless/labels.d.ts +19 -1
  218. package/dist/session/headless/labels.js +15 -1
  219. package/dist/session/headless/queue.js +2 -1
  220. package/dist/session/headless/reminder-labels.d.ts +4 -0
  221. package/dist/session/headless/reminder-labels.js +4 -0
  222. package/dist/settings/SettingsRestricted.d.ts +1 -1
  223. package/dist/settings/SettingsRestricted.js +4 -4
  224. package/dist/settings/SettingsShell.d.ts +7 -0
  225. package/dist/settings/SettingsShell.js +6 -1
  226. package/dist/settings/headless/fixture-performance.d.ts +1 -1
  227. package/dist/settings/headless/host.d.ts +2 -2
  228. package/dist/settings/headless/labels.d.ts +3 -3
  229. package/dist/settings/headless/labels.js +3 -3
  230. package/dist/settings/headless/performance.d.ts +3 -4
  231. package/dist/settings/headless/search.d.ts +1 -1
  232. package/dist/settings/index.d.ts +2 -1
  233. package/dist/settings/index.js +2 -1
  234. package/dist/settings/sections/editor/EditorSection.js +7 -4
  235. package/dist/settings/sections/editor/labels.d.ts +1 -0
  236. package/dist/settings/sections/editor/labels.js +1 -0
  237. package/dist/settings/sections/environments/EnvironmentsSection.js +19 -12
  238. package/dist/settings/sections/environments/labels.d.ts +1 -0
  239. package/dist/settings/sections/environments/labels.js +2 -1
  240. package/dist/settings/sections/extensions/ExtensionConfigRows.d.ts +1 -3
  241. package/dist/settings/sections/extensions/ExtensionConfigRows.js +20 -19
  242. package/dist/settings/sections/extensions/ExtensionOptionsSection.js +2 -1
  243. package/dist/settings/sections/extensions/options-labels.d.ts +2 -1
  244. package/dist/settings/sections/extensions/options-labels.js +2 -1
  245. package/dist/settings/sections/index.d.ts +2 -1
  246. package/dist/settings/sections/index.js +2 -1
  247. package/dist/settings/sections/logs/LogsSection.d.ts +2 -2
  248. package/dist/settings/sections/logs/LogsSection.js +2 -2
  249. package/dist/settings/sections/mcp/McpSection.d.ts +1 -1
  250. package/dist/settings/sections/mcp/McpSection.js +12 -6
  251. package/dist/settings/sections/mcp/McpServerRow.js +20 -13
  252. package/dist/settings/sections/mcp/labels.d.ts +8 -2
  253. package/dist/settings/sections/mcp/labels.js +8 -2
  254. package/dist/settings/sections/models/ModelRows.js +1 -1
  255. package/dist/settings/sections/models/NewChatPlaceRow.d.ts +26 -0
  256. package/dist/settings/sections/models/NewChatPlaceRow.js +78 -0
  257. package/dist/settings/sections/models/SpacesDefaultsSection.js +15 -3
  258. package/dist/settings/sections/models/labels.d.ts +7 -0
  259. package/dist/settings/sections/models/labels.js +7 -0
  260. package/dist/settings/sections/models/model-test.js +7 -4
  261. package/dist/settings/sections/performance/PerformanceSection.js +16 -6
  262. package/dist/settings/sections/performance/labels.d.ts +1 -1
  263. package/dist/settings/sections/performance/labels.js +1 -1
  264. package/dist/settings/sections/providers/ProvidersSection.d.ts +1 -1
  265. package/dist/settings/sections/providers/ProvidersSection.js +14 -7
  266. package/dist/settings/sections/providers/ServerProvidersSection.d.ts +1 -1
  267. package/dist/settings/sections/providers/ServerProvidersSection.js +11 -5
  268. package/dist/settings/sections/providers/labels.d.ts +2 -2
  269. package/dist/settings/sections/providers/labels.js +2 -2
  270. package/dist/settings/sections/skills/SkillList.js +1 -1
  271. package/dist/settings/sections/skills/SkillsSection.js +1 -1
  272. package/dist/settings/testing/performance.contract.js +8 -12
  273. package/dist/styles.css +32 -3
  274. package/dist/terminal/HostTerminalSurface.js +15 -5
  275. package/dist/terminal/TerminalPanel.js +30 -17
  276. package/dist/terminal/TerminalSurface.js +11 -4
  277. package/dist/terminal/headless/labels.d.ts +5 -0
  278. package/dist/terminal/headless/labels.js +5 -0
  279. package/dist/terminal/headless/store.d.ts +1 -1
  280. package/dist/terminal/headless/store.js +6 -3
  281. package/dist/workspace/LayoutBudget.d.ts +5 -1
  282. package/dist/workspace/LayoutBudget.js +14 -1
  283. package/dist/workspace/PanelContentView.d.ts +1 -1
  284. package/dist/workspace/PanelContentView.js +17 -6
  285. package/dist/workspace/WorkspaceProvider.js +3 -2
  286. package/dist/workspace/headless/labels.d.ts +1 -0
  287. package/dist/workspace/headless/labels.js +1 -0
  288. package/package.json +3 -3
  289. package/src/styles/motion.css +8 -0
  290. package/src/styles/primitives.css +7 -0
@@ -1,4 +1,5 @@
1
1
  import { buttonClass } from "../../components/button.js";
2
+ import { Notice } from "../../components/Notice.js";
2
3
  import { jsx } from "react/jsx-runtime";
3
4
  import { useEffect, useRef } from "react";
4
5
  //#region src/chat/interactions/card-ui.tsx
@@ -27,15 +28,16 @@ const INPUT = `${FIELD} w-full placeholder:text-[var(--zg-text-subtle)]`;
27
28
  /**
28
29
  * Renders an inline error message, or nothing when there is none.
29
30
  *
30
- * @param props - Component props: the `error` text.
31
+ * @param props - Component props: the `error` message and its raw `detail`.
31
32
  */
32
- function CardError({ error, className, style }) {
33
+ function CardError({ error, detail, className, style }) {
33
34
  if (!error) return null;
34
- return /* @__PURE__ */ jsx("span", {
35
- role: "alert",
36
- className: ["min-w-0 truncate text-zg-meta text-[var(--zg-error)]", className].filter(Boolean).join(" "),
37
- style,
38
- title: error,
35
+ return /* @__PURE__ */ jsx(Notice, {
36
+ tone: "error",
37
+ compact: true,
38
+ ...detail ? { detail } : {},
39
+ className: ["min-w-0", className].filter(Boolean).join(" "),
40
+ ...style ? { style } : {},
39
41
  children: error
40
42
  });
41
43
  }
@@ -68,11 +68,6 @@ function RichComposer({ disabled, folderPath, fileRoot, activeSessionId = null,
68
68
  const history = usePromptHistory();
69
69
  const [historyStatus, setHistoryStatus] = useState(null);
70
70
  const editorRef = useRef(null);
71
- const runningPlaceholder = running ? messageDelivery === "steer" ? labels.placeholderSteer : labels.placeholderQueue : null;
72
- const runningPlaceholderRef = useRef(runningPlaceholder);
73
- useLayoutEffect(() => {
74
- runningPlaceholderRef.current = runningPlaceholder;
75
- });
76
71
  const liveEditor = () => {
77
72
  const ed = editorRef.current;
78
73
  return ed && !ed.isDestroyed ? ed : null;
@@ -157,7 +152,6 @@ function RichComposer({ disabled, folderPath, fileRoot, activeSessionId = null,
157
152
  history,
158
153
  activeSessionId,
159
154
  hostId,
160
- runningPlaceholderRef,
161
155
  send: (alternate) => send(alternate),
162
156
  onSearchNavigate,
163
157
  applyMode,
@@ -295,7 +289,7 @@ function RichComposer({ disabled, folderPath, fileRoot, activeSessionId = null,
295
289
  useEffect(() => {
296
290
  const ed = editorRef.current;
297
291
  if (ed && !ed.isDestroyed) ed.view.dispatch(ed.state.tr);
298
- }, [composerMode, runningPlaceholder]);
292
+ }, [composerMode]);
299
293
  useEffect(() => {
300
294
  if (modeRef.current === "search") liveEditor()?.commands.clearContent(true);
301
295
  live.current.applyMode("normal");
@@ -32,8 +32,6 @@ interface ComposerExtensionsContext {
32
32
  modeRef: RefObject<ComposerMode>;
33
33
  /** Re-evaluate the ghost after a gate input flipped without an edit. */
34
34
  ghostGateChangedRef: RefObject<() => void>;
35
- /** The placeholder while a run works (what Enter and Alt+Enter do), `null` otherwise. */
36
- runningPlaceholderRef: RefObject<string | null>;
37
35
  labels: ComposerLabels;
38
36
  }
39
37
  /** The editor's extensions. */
@@ -28,7 +28,7 @@ const MentionChat = Mention.extend({ name: "mentionChat" });
28
28
  const MAX_RESULTS = 8;
29
29
  /** The editor's extensions. */
30
30
  function composerExtensions(ctx) {
31
- const { disabled, folderPath, extensionCompletionProviders, extensionItems, sources, filesProvider, slashSource, chatsProvider, chatScopeRef, mentionPopovers, promptGhost, modeRef, ghostGateChangedRef, runningPlaceholderRef, labels } = ctx;
31
+ const { disabled, folderPath, extensionCompletionProviders, extensionItems, sources, filesProvider, slashSource, chatsProvider, chatScopeRef, mentionPopovers, promptGhost, modeRef, ghostGateChangedRef, labels } = ctx;
32
32
  const chatScopeLabel = (scope) => scope === "project" ? labels.chatScopeProject : labels.chatScopeAll;
33
33
  return [
34
34
  StarterKit.configure({
@@ -54,7 +54,7 @@ function composerExtensions(ctx) {
54
54
  if (promptGhost.painted()) return "";
55
55
  if (modeRef.current === "shell") return labels.placeholderShell;
56
56
  if (modeRef.current === "search") return labels.placeholderSearch;
57
- return runningPlaceholderRef.current ?? labels.placeholderChat;
57
+ return labels.placeholderChat;
58
58
  }
59
59
  }),
60
60
  Mention.configure({
@@ -23,8 +23,6 @@ interface ComposerEditorOptions {
23
23
  /** The live editor (the one this hook returns, once pinned). */
24
24
  editorRef: RefObject<Editor | null>;
25
25
  modeRef: RefObject<ComposerMode>;
26
- /** The placeholder while a run works, `null` otherwise. */
27
- runningPlaceholderRef: RefObject<string | null>;
28
26
  /** The inline ghost on display. */
29
27
  ghostRef: RefObject<InlineGhost | null>;
30
28
  /** True while a history recall's own transactions run (no ghost for them). */
@@ -18,7 +18,7 @@ import { useEditor } from "@tiptap/react";
18
18
  * state through the refs it passes.
19
19
  */
20
20
  function useComposerEditor(options) {
21
- const { disabled, folderPath, extensionCompletionProviders, sources, skillsProvider, mentionPopovers, promptGhost, modeRef, runningPlaceholderRef, ghostGateChangedRef } = options;
21
+ const { disabled, folderPath, extensionCompletionProviders, sources, skillsProvider, mentionPopovers, promptGhost, modeRef, ghostGateChangedRef } = options;
22
22
  const completions = useComposerHost().completions;
23
23
  const labels = useComposerLabels();
24
24
  const latest = useRef(options);
@@ -85,7 +85,6 @@ function useComposerEditor(options) {
85
85
  promptGhost,
86
86
  modeRef,
87
87
  ghostGateChangedRef,
88
- runningPlaceholderRef,
89
88
  labels
90
89
  }),
91
90
  editable: !disabled,
@@ -1,4 +1,5 @@
1
1
  import { useWithFade } from "../../motion/springs.js";
2
+ import { errorMessage } from "../../components/report-error.js";
2
3
  import { basename } from "../../path.js";
3
4
  import { useExtensionsHost } from "../../extensions/ExtensionsProvider.js";
4
5
  import { useSidebarNotice } from "./SidebarHostProvider.js";
@@ -133,7 +134,6 @@ function NewSessionButton({ onNewSession, isActive, className = "", style }) {
133
134
  })
134
135
  });
135
136
  }
136
- const messageOf = (err) => err?.message ?? String(err);
137
137
  const NO_ITEMS = [];
138
138
  const NO_DECORATIONS = [];
139
139
  /**
@@ -339,14 +339,14 @@ function SessionSidebar(props) {
339
339
  });
340
340
  }, [onDelete]);
341
341
  const onRowMoveToSpace = useCallback((sessionId, spaceId) => {
342
- onMoveToSpace?.(sessionId, spaceId).catch((err) => notify(labels.moveSessionFailed(messageOf(err))));
342
+ onMoveToSpace?.(sessionId, spaceId).catch((err) => notify(labels.moveSessionFailed(errorMessage(err))));
343
343
  }, [
344
344
  onMoveToSpace,
345
345
  notify,
346
346
  labels
347
347
  ]);
348
348
  const onRowMoveProjectToSpace = useCallback((project, spaceId) => {
349
- onMoveProjectToSpace?.(project, spaceId).catch((err) => notify(labels.moveProjectFailed(messageOf(err))));
349
+ onMoveProjectToSpace?.(project, spaceId).catch((err) => notify(labels.moveProjectFailed(errorMessage(err))));
350
350
  }, [
351
351
  onMoveProjectToSpace,
352
352
  notify,
@@ -361,7 +361,7 @@ function SessionSidebar(props) {
361
361
  if (!open) return;
362
362
  if (onOpenItem) return onOpenItem(open, entry);
363
363
  if ("session" in open) commitImmediate(open.session);
364
- else if ("command" in open) runCommand?.(open.command, { args: entry.item.args }).catch((err) => notify(labels.itemOpenFailed(messageOf(err))));
364
+ else if ("command" in open) runCommand?.(open.command, { args: entry.item.args }).catch((err) => notify(labels.itemOpenFailed(errorMessage(err))));
365
365
  else if ("panel" in open) workspace?.focusTab(open.panel);
366
366
  else openScreen(open.screen);
367
367
  }, [
@@ -375,7 +375,7 @@ function SessionSidebar(props) {
375
375
  ]);
376
376
  const onRunItemAction = useCallback((entry, action) => {
377
377
  if (!action.command || !runCommand) return;
378
- runCommand(action.command, { args: entry.item.args }).catch((err) => notify(labels.itemOpenFailed(messageOf(err))));
378
+ runCommand(action.command, { args: entry.item.args }).catch((err) => notify(labels.itemOpenFailed(errorMessage(err))));
379
379
  }, [
380
380
  runCommand,
381
381
  notify,
@@ -1,6 +1,7 @@
1
1
  import { useChatLabels } from "../useChatLabels.js";
2
2
  import { SessionFilterMenu } from "../SessionFilterMenu.js";
3
3
  import { VIEW_CHOICE } from "../headless/sidebar/types.js";
4
+ import { DEFAULT_SIDEBAR_VIEW } from "../headless/sidebar/view.js";
4
5
  import { useAgentNames } from "./useAgentNames.js";
5
6
  import { jsx } from "react/jsx-runtime";
6
7
  import { useMemo } from "react";
@@ -23,6 +24,7 @@ const VIEWS_WITH_HOST = [
23
24
  const SORTS = [
24
25
  "alphabetical",
25
26
  "createdTime",
27
+ "lastUserMessage",
26
28
  "recency"
27
29
  ];
28
30
  const ALL_AGENTS = "__all__";
@@ -179,7 +181,7 @@ function SidebarFilterMenu({ view, projects, onChange, hosts = false, agents, ag
179
181
  label: labels.filterSort,
180
182
  placement: "sort",
181
183
  value: options.find((o) => o.id === current)?.label ?? current,
182
- atDefault: current === (space?.sortBy ? SPACE : "recency"),
184
+ atDefault: current === (space?.sortBy ? SPACE : DEFAULT_SIDEBAR_VIEW.sortBy),
183
185
  options,
184
186
  current,
185
187
  onChange: (next) => {
@@ -22,6 +22,10 @@ interface SidebarFrameState {
22
22
  mounted: boolean;
23
23
  /** Fully open (not entering or closing). */
24
24
  open: boolean;
25
+ /** Open over the chat: the window is too narrow to dock it (`LayoutBudget.sidebarPeek`). */
26
+ overlay: boolean;
27
+ /** Closes it when it is open over the chat. */
28
+ closeOverlay: () => void;
25
29
  /** The width shown (px). */
26
30
  width: number;
27
31
  /** The aside, for the drag's live CSS var. */
@@ -2,8 +2,8 @@ import { readPanelMs, usePresence } from "../../motion/presence.js";
2
2
  import { useResizeDrag } from "../../hooks/useResizeDrag.js";
3
3
  import { DEFAULT_APPEARANCE, LIMITS } from "../../appearance/headless/prefs.js";
4
4
  import { useLayoutBudgetOptional } from "../../workspace/LayoutBudget.js";
5
- import { jsx, jsxs } from "react/jsx-runtime";
6
- import { useRef } from "react";
5
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
+ import { useEffect, useRef } from "react";
7
7
  //#region src/chat/sidebar/SidebarFrame.tsx
8
8
  /**
9
9
  * The frame's presence, width and drag.
@@ -13,11 +13,13 @@ import { useRef } from "react";
13
13
  function useSidebarFrame(options) {
14
14
  const { collapsed, width: wanted, onWidthCommit, minWidth = LIMITS.sidebarWidth.min, maxWidth = LIMITS.sidebarWidth.max, defaultWidth = DEFAULT_APPEARANCE.sidebarWidth } = options;
15
15
  const budget = useLayoutBudgetOptional();
16
- const presence = usePresence(!collapsed && !(budget?.sidebarForcedCollapsed ?? false), {
16
+ const forced = budget?.sidebarForcedCollapsed ?? false;
17
+ const overlay = forced && (budget?.sidebarPeek ?? false);
18
+ const presence = usePresence(forced ? overlay : !collapsed, {
17
19
  enter: true,
18
20
  exitMs: readPanelMs
19
21
  });
20
- const width = budget && budget.sidebarWidth > 0 ? budget.sidebarWidth : wanted;
22
+ const width = overlay ? Math.min(wanted, Math.max(minWidth, (budget?.chatWidth ?? wanted) - 48)) : budget && budget.sidebarWidth > 0 ? budget.sidebarWidth : wanted;
21
23
  const asideRef = useRef(null);
22
24
  const max = budget ? Math.max(minWidth, budget.getCaps().sidebarMax) : maxWidth;
23
25
  const drag = useResizeDrag({
@@ -32,9 +34,12 @@ function useSidebarFrame(options) {
32
34
  },
33
35
  onCommit: onWidthCommit
34
36
  });
37
+ const closeOverlay = () => budget?.peekSidebar(false);
35
38
  return {
36
39
  mounted: presence.mounted,
37
40
  open: presence.state === "open",
41
+ overlay,
42
+ closeOverlay,
38
43
  width,
39
44
  asideRef,
40
45
  drag
@@ -46,13 +51,26 @@ function useSidebarFrame(options) {
46
51
  * @param props - The frame state, the chrome inset, the content, its name, `className` and `style`.
47
52
  */
48
53
  function SidebarFrame({ frame, chromeInset, children, ariaLabel, className = "", style }) {
49
- const { open, width, asideRef, drag } = frame;
50
- return /* @__PURE__ */ jsxs("aside", {
54
+ const { open, overlay, closeOverlay, width, asideRef, drag } = frame;
55
+ useEffect(() => {
56
+ if (!overlay) return void 0;
57
+ const onKey = (event) => {
58
+ if (event.key === "Escape") closeOverlay();
59
+ };
60
+ window.addEventListener("keydown", onKey);
61
+ return () => window.removeEventListener("keydown", onKey);
62
+ }, [overlay, closeOverlay]);
63
+ return /* @__PURE__ */ jsxs(Fragment, { children: [overlay && /* @__PURE__ */ jsx("div", {
64
+ "aria-hidden": true,
65
+ className: "fixed inset-0 z-40 bg-black/30",
66
+ onClick: closeOverlay
67
+ }), /* @__PURE__ */ jsxs("aside", {
51
68
  ref: asideRef,
52
69
  ...ariaLabel ? { "aria-label": ariaLabel } : {},
53
70
  "data-collapsed": !open,
54
71
  "aria-hidden": !open,
55
- className: `zg-sidebar relative z-[2] shrink-0 h-full bg-[var(--zg-tray)]${className ? ` ${className}` : ""}`,
72
+ "data-overlay": overlay || void 0,
73
+ className: `zg-sidebar ${overlay ? "fixed left-0 top-0 z-zg-overlay shadow-[var(--zg-shadow-float)]" : "relative z-[2]"} shrink-0 h-full bg-[var(--zg-tray)]${className ? ` ${className}` : ""}`,
56
74
  style: {
57
75
  "--zg-sidebar-w": `${width}px`,
58
76
  ...style
@@ -68,12 +86,12 @@ function SidebarFrame({ frame, chromeInset, children, ariaLabel, className = "",
68
86
  style: { width: chromeInset.width }
69
87
  })
70
88
  }), children]
71
- }), open && /* @__PURE__ */ jsx("div", {
89
+ }), open && !overlay && /* @__PURE__ */ jsx("div", {
72
90
  ...drag.handleProps,
73
91
  "data-active": drag.active,
74
92
  className: "zg-resize-handle zg-no-drag -right-1"
75
93
  })]
76
- });
94
+ })] });
77
95
  }
78
96
  //#endregion
79
97
  export { SidebarFrame, useSidebarFrame };
@@ -144,7 +144,7 @@ function SidebarGroupHeader({ row, groupBy, icon, onAssignIcon, onToggle, onNewS
144
144
  label: pinned ? labels.unpinNamed(row.label) : labels.pinNamed(row.label),
145
145
  size: "xs",
146
146
  "aria-pressed": pinned,
147
- className: pinned ? void 0 : "zg-row-dots",
147
+ className: "zg-row-dots",
148
148
  onClick: (event) => {
149
149
  event.stopPropagation();
150
150
  onSetPinned(row.fullPath, !pinned);
@@ -1,12 +1,15 @@
1
1
  import { SidebarHost } from "../headless/sidebar/host.js";
2
+ import { NoticeTone } from "../../components/Notice.js";
2
3
  import { ReactNode } from "react";
3
4
  //#region src/chat/sidebar/SidebarHostProvider.d.ts
5
+ /** Tells the user a command's outcome, worded for people: `error` unless a `tone` says otherwise. */
6
+ type SidebarNotify = (message: string, tone?: NoticeTone) => void;
4
7
  /** Props of {@link SidebarHostProvider}. */
5
8
  interface SidebarHostProviderProps {
6
9
  /** The platform's sidebar capabilities. */
7
10
  host: SidebarHost;
8
- /** Tells the user a command's outcome or failure. Default: the browser's `alert`. */
9
- notify?: (message: string) => void;
11
+ /** Tells the user a command's outcome or failure. Default: the app's notice stack (`useNotify`). */
12
+ notify?: SidebarNotify;
10
13
  /** The app's components. */
11
14
  children: ReactNode;
12
15
  }
@@ -18,7 +21,7 @@ interface SidebarHostProviderProps {
18
21
  declare function SidebarHostProvider({ host, notify, children }: SidebarHostProviderProps): import("react").JSX.Element;
19
22
  /** The nearest {@link SidebarHost}; an empty host (every capability left out) outside a provider. */
20
23
  declare function useSidebarHost(): SidebarHost;
21
- /** How the nearest {@link SidebarHostProvider} tells the user something. */
22
- declare function useSidebarNotice(): (message: string) => void;
24
+ /** How the nearest {@link SidebarHostProvider} tells the user something: its `notify`, else the app's notice stack. */
25
+ declare function useSidebarNotice(): SidebarNotify;
23
26
  //#endregion
24
- export { SidebarHostProvider, SidebarHostProviderProps, useSidebarHost, useSidebarNotice };
27
+ export { SidebarHostProvider, SidebarHostProviderProps, SidebarNotify, useSidebarHost, useSidebarNotice };
@@ -1,27 +1,25 @@
1
+ import { useNotify } from "../../app/NoticeStack.js";
1
2
  import { jsx } from "react/jsx-runtime";
2
- import { createContext, useContext, useMemo } from "react";
3
+ import { createContext, useCallback, useContext, useMemo } from "react";
3
4
  //#region src/chat/sidebar/SidebarHostProvider.tsx
4
5
  /**
5
6
  * Puts a `SidebarHost` in context for the sidebar's rows and every other
6
7
  * surface that offers a session's menu (the session header), with the way
7
8
  * the app tells the user a command's outcome (`notify`).
8
9
  */
9
- const browserAlert = (message) => {
10
- globalThis.alert?.(message);
11
- };
12
10
  const SidebarHostContext = createContext({
13
11
  host: {},
14
- notify: browserAlert
12
+ notify: null
15
13
  });
16
14
  /**
17
15
  * Provides a {@link SidebarHost} to the sidebar and the session menus below.
18
16
  *
19
17
  * @param props - The `host`, an optional `notify` and the `children`.
20
18
  */
21
- function SidebarHostProvider({ host, notify = browserAlert, children }) {
19
+ function SidebarHostProvider({ host, notify = void 0, children }) {
22
20
  const value = useMemo(() => ({
23
21
  host,
24
- notify
22
+ notify: notify ?? null
25
23
  }), [host, notify]);
26
24
  return /* @__PURE__ */ jsx(SidebarHostContext.Provider, {
27
25
  value,
@@ -32,9 +30,15 @@ function SidebarHostProvider({ host, notify = browserAlert, children }) {
32
30
  function useSidebarHost() {
33
31
  return useContext(SidebarHostContext).host;
34
32
  }
35
- /** How the nearest {@link SidebarHostProvider} tells the user something. */
33
+ /** How the nearest {@link SidebarHostProvider} tells the user something: its `notify`, else the app's notice stack. */
36
34
  function useSidebarNotice() {
37
- return useContext(SidebarHostContext).notify;
35
+ const own = useContext(SidebarHostContext).notify;
36
+ const notify = useNotify();
37
+ const viaStack = useCallback((message, tone = "error") => notify({
38
+ tone,
39
+ message
40
+ }), [notify]);
41
+ return own ?? viaStack;
38
42
  }
39
43
  //#endregion
40
44
  export { SidebarHostProvider, useSidebarHost, useSidebarNotice };
@@ -11,12 +11,16 @@ import { jsx } from "react/jsx-runtime";
11
11
  function SidebarToggleButton({ collapsed: collapsedProp, onClick, className = "", style }) {
12
12
  const labels = useSidebarLabels();
13
13
  const budget = useLayoutBudgetOptional();
14
- const collapsed = collapsedProp || (budget?.sidebarForcedCollapsed ?? false);
14
+ const forced = budget?.sidebarForcedCollapsed ?? false;
15
+ const collapsed = forced ? !budget?.sidebarPeek : collapsedProp;
15
16
  return /* @__PURE__ */ jsx(IconButton, {
16
17
  icon: "i-ph-sidebar",
17
18
  label: collapsed ? labels.expandSidebar : labels.collapseSidebar,
18
- onClick,
19
- style,
19
+ onClick: forced ? () => budget?.peekSidebar(!budget.sidebarPeek) : onClick,
20
+ style: forced && budget?.sidebarPeek ? {
21
+ ...style,
22
+ zIndex: 51
23
+ } : style,
20
24
  className: `zg-hit-extend ${className}`
21
25
  });
22
26
  }
@@ -10,7 +10,7 @@ import { NewSessionButton, NewSessionButtonProps, SessionSidebar, SessionSidebar
10
10
  import { SidebarChip, SidebarChipProps, SidebarDecoration, SidebarDecorationProps } from "./SidebarDecoration.js";
11
11
  import { SidebarFilterMenu, SidebarFilterMenuProps } from "./SidebarFilterMenu.js";
12
12
  import { SidebarCompactingIndicator, SidebarCompactingIndicatorProps, SidebarFooter, SidebarFooterProps, SidebarSettingsNote, SidebarSignInPrompt, SidebarSignInPromptProps, SidebarUsageIndicator, SidebarUsageIndicatorProps } from "./SidebarFooter.js";
13
- import { SidebarHostProvider, SidebarHostProviderProps, useSidebarHost, useSidebarNotice } from "./SidebarHostProvider.js";
13
+ import { SidebarHostProvider, SidebarHostProviderProps, SidebarNotify, useSidebarHost, useSidebarNotice } from "./SidebarHostProvider.js";
14
14
  import { SidebarRowView, SidebarRowViewProps } from "./SidebarRowView.js";
15
15
  import { SidebarSearchRow, SidebarSearchRowProps } from "./SidebarSearchRow.js";
16
16
  import { SidebarRowHandlers, SidebarSessionRow, SidebarSessionRowProps } from "./SidebarSessionRow.js";
@@ -27,4 +27,4 @@ import { SessionDirectoryView, useSessionDirectoryView } from "./useSessionDirec
27
27
  import { useMainSession } from "./use-main-session.js";
28
28
  import { useSaveViewAsSpace } from "./useSaveViewAsSpace.js";
29
29
  import { SidebarKeyboardNavOptions, useSidebarKeyboardNav } from "./useSidebarKeyboardNav.js";
30
- export { ARRIVAL_MS, type BadgeCardPlacement, EnvironmentChip, type EnvironmentChipProps, ICON_PICKER_WIDTH, IconPicker, type IconPickerProps, MainSessionRow, type MainSessionRowProps, NewSessionButton, type NewSessionButtonProps, ProjectChip, type ProjectChipProps, ProjectIconButton, type ProjectIconButtonProps, ProjectIconGlyph, type ProjectIconGlyphProps, type RowProject, type SessionContentSearch, type SessionDirectoryView, type SessionMenuActions, type SessionMenuContext, type SessionMenuSurfaceActions, type SessionMenuTarget, SessionSidebar, type SessionSidebarProps, type SidebarBadgeFocus, SidebarChip, type SidebarChipProps, type SidebarChromeInset, type SidebarCollapsedStore, SidebarCompactingIndicator, type SidebarCompactingIndicatorProps, SidebarDecoration, type SidebarDecorationProps, SidebarFilterMenu, type SidebarFilterMenuProps, SidebarFooter, type SidebarFooterProps, SidebarFrame, type SidebarFrameOptions, type SidebarFrameProps, type SidebarFrameState, SidebarGroupHeader, type SidebarGroupHeaderProps, type SidebarHeaderRow, SidebarHostProvider, type SidebarHostProviderProps, type SidebarKeyboardNavOptions, type SidebarLive, type SidebarLiveOptions, type SidebarProject, type SidebarProjectRef, type SidebarRowArtifactsProps, type SidebarRowHandlers, type SidebarRowMetaProps, type SidebarRowSession, SidebarRowView, type SidebarRowViewProps, SidebarSearchRow, type SidebarSearchRowProps, SidebarSessionRow, type SidebarSessionRowProps, type SidebarSettingsNote, SidebarSignInPrompt, type SidebarSignInPromptProps, type SidebarSpaceSlide, SidebarToggleButton, type SidebarToggleButtonProps, SidebarUsageIndicator, type SidebarUsageIndicatorProps, SpaceGlyph, type SpaceGlyphProps, SpaceSwitcher, type SpaceSwitcherProps, SpacesSection, type SpacesSectionProps, archiveProjectPrompt, createSidebarCollapsed, createSidebarLive, deleteProjectPrompt, sessionMenuItems, spaceRows, useArrival, useCompactionProgress, useConfirmDeleteSession, useEnvironmentActions, useEnvironmentCommands, useMainSession, usePinnedProjects, useProjectIcons, useProjectSessionActions, useSaveViewAsSpace, useSessionActivity, useSessionBadges, useSessionDirectoryView, useSessionMenuItems, useSessionSearch, useSidebarFrame, useSidebarHost, useSidebarKeyboardNav, useSidebarLabels, useSidebarNotice };
30
+ export { ARRIVAL_MS, type BadgeCardPlacement, EnvironmentChip, type EnvironmentChipProps, ICON_PICKER_WIDTH, IconPicker, type IconPickerProps, MainSessionRow, type MainSessionRowProps, NewSessionButton, type NewSessionButtonProps, ProjectChip, type ProjectChipProps, ProjectIconButton, type ProjectIconButtonProps, ProjectIconGlyph, type ProjectIconGlyphProps, type RowProject, type SessionContentSearch, type SessionDirectoryView, type SessionMenuActions, type SessionMenuContext, type SessionMenuSurfaceActions, type SessionMenuTarget, SessionSidebar, type SessionSidebarProps, type SidebarBadgeFocus, SidebarChip, type SidebarChipProps, type SidebarChromeInset, type SidebarCollapsedStore, SidebarCompactingIndicator, type SidebarCompactingIndicatorProps, SidebarDecoration, type SidebarDecorationProps, SidebarFilterMenu, type SidebarFilterMenuProps, SidebarFooter, type SidebarFooterProps, SidebarFrame, type SidebarFrameOptions, type SidebarFrameProps, type SidebarFrameState, SidebarGroupHeader, type SidebarGroupHeaderProps, type SidebarHeaderRow, SidebarHostProvider, type SidebarHostProviderProps, type SidebarKeyboardNavOptions, type SidebarLive, type SidebarLiveOptions, type SidebarNotify, type SidebarProject, type SidebarProjectRef, type SidebarRowArtifactsProps, type SidebarRowHandlers, type SidebarRowMetaProps, type SidebarRowSession, SidebarRowView, type SidebarRowViewProps, SidebarSearchRow, type SidebarSearchRowProps, SidebarSessionRow, type SidebarSessionRowProps, type SidebarSettingsNote, SidebarSignInPrompt, type SidebarSignInPromptProps, type SidebarSpaceSlide, SidebarToggleButton, type SidebarToggleButtonProps, SidebarUsageIndicator, type SidebarUsageIndicatorProps, SpaceGlyph, type SpaceGlyphProps, SpaceSwitcher, type SpaceSwitcherProps, SpacesSection, type SpacesSectionProps, archiveProjectPrompt, createSidebarCollapsed, createSidebarLive, deleteProjectPrompt, sessionMenuItems, spaceRows, useArrival, useCompactionProgress, useConfirmDeleteSession, useEnvironmentActions, useEnvironmentCommands, useMainSession, usePinnedProjects, useProjectIcons, useProjectSessionActions, useSaveViewAsSpace, useSessionActivity, useSessionBadges, useSessionDirectoryView, useSessionMenuItems, useSessionSearch, useSidebarFrame, useSidebarHost, useSidebarKeyboardNav, useSidebarLabels, useSidebarNotice };
@@ -1,3 +1,4 @@
1
+ import { errorMessage } from "../../components/report-error.js";
1
2
  import { useSidebarHost, useSidebarNotice } from "./SidebarHostProvider.js";
2
3
  import { useLinkRouter } from "../../extensions/links.js";
3
4
  import { useConfirm } from "../../app/useConfirm.js";
@@ -163,7 +164,6 @@ function useEnvironmentActions(sessionId, enabled) {
163
164
  ]);
164
165
  return actions;
165
166
  }
166
- const messageOf = (err) => err?.message ?? String(err);
167
167
  /**
168
168
  * Running an environment command (open what it returns, else say what happened) and setting a failed
169
169
  * environment up again, worded through the labels and told with the provider's `notify`. Stable identities.
@@ -180,8 +180,8 @@ function useEnvironmentCommands() {
180
180
  source: "other",
181
181
  sessionId
182
182
  });
183
- else notify(result.message);
184
- }).catch((err) => notify(labels.environmentActionFailed(label, messageOf(err))));
183
+ else notify(result.message, "info");
184
+ }).catch((err) => notify(labels.environmentActionFailed(label, errorMessage(err))));
185
185
  }, [
186
186
  environment,
187
187
  notify,
@@ -189,7 +189,7 @@ function useEnvironmentCommands() {
189
189
  links
190
190
  ]);
191
191
  const retry = useCallback((sessionId) => {
192
- environment?.retry(sessionId).catch((err) => notify(labels.retryEnvironmentFailed(messageOf(err))));
192
+ environment?.retry(sessionId).catch((err) => notify(labels.retryEnvironmentFailed(errorMessage(err))));
193
193
  }, [
194
194
  environment,
195
195
  notify,
@@ -1,3 +1,4 @@
1
+ import { errorMessage } from "../../components/report-error.js";
1
2
  import { useSidebarNotice } from "./SidebarHostProvider.js";
2
3
  import { useSidebarLabels } from "./useSidebarLabels.js";
3
4
  import { nextSavedViewName } from "../headless/sidebar/query.js";
@@ -9,7 +10,6 @@ import { useCallback, useRef } from "react";
9
10
  * the user when the save fails (`labels.saveViewFailed` through the nearest
10
11
  * `SidebarHostProvider`'s `notify`), so every app saves views the same way.
11
12
  */
12
- const messageOf = (err) => err instanceof Error ? err.message : String(err);
13
13
  /**
14
14
  * The filter menu's `onSaveView` over a directory's `saveViewAsSpace`: saves the shown view under
15
15
  * the next free saved-view name; a failure (an invalid query, a settings write that failed) shows
@@ -36,7 +36,7 @@ function useSaveViewAsSpace(save, spaces) {
36
36
  const onSave = useCallback(() => {
37
37
  const { save: run, spaces: all, labels: words, notify: tell } = latest.current;
38
38
  if (!run) return;
39
- run(nextSavedViewName(all, words.savedViewName)).catch((err) => tell(words.saveViewFailed(messageOf(err))));
39
+ run(nextSavedViewName(all, words.savedViewName)).catch((err) => tell(words.saveViewFailed(errorMessage(err))));
40
40
  }, []);
41
41
  return save ? onSave : void 0;
42
42
  }
@@ -524,9 +524,9 @@ function describeChatHostContract(name, makeHarness, capabilities) {
524
524
  it.skipIf(!has("sessions", "sessions.onChanged", "sessions.rename"))("signals a changed session", async () => {
525
525
  const { host } = await setup();
526
526
  const seen = [];
527
- cleanup.push(host.sessions.onChanged((id) => seen.push(id)));
527
+ cleanup.push(host.sessions.onChanged((change) => seen.push(change.op === "delete" ? "" : change.row?.title ?? "")));
528
528
  await host.sessions.rename("c-2", "Renamed");
529
- await waitFor(() => expect(seen).toContain("c-2"));
529
+ await waitFor(() => expect(seen).toContain("Renamed"));
530
530
  });
531
531
  it.skipIf(!has("sessions", "sessions.views"))("keeps the sidebar views and the shown space", async () => {
532
532
  const { host } = await setup();
@@ -1,4 +1,5 @@
1
1
  import { buttonClass } from "../../components/button.js";
2
+ import { Notice } from "../../components/Notice.js";
2
3
  import "../../components/Form.js";
3
4
  import { useReadable } from "../headless/store.js";
4
5
  import { RoutedLink } from "../../extensions/links.js";
@@ -216,10 +217,11 @@ const AuthFailureCard = memo(function AuthFailureCard({ auth, text, detail, fail
216
217
  onCancel: signIn.cancel
217
218
  }) : flow?.kind === "error" ? /* @__PURE__ */ jsxs("div", {
218
219
  className: "flex flex-col gap-1.5",
219
- children: [/* @__PURE__ */ jsx("div", {
220
- role: "alert",
221
- className: "text-zg-danger break-words",
222
- children: labels.authFailed(flow.message)
220
+ children: [/* @__PURE__ */ jsx(Notice, {
221
+ tone: "error",
222
+ compact: true,
223
+ detail: flow.message,
224
+ children: labels.authSignInFailed
223
225
  }), /* @__PURE__ */ jsxs("div", {
224
226
  className: "flex flex-wrap items-center gap-1.5",
225
227
  children: [/* @__PURE__ */ jsx("button", {
@@ -236,10 +238,11 @@ const AuthFailureCard = memo(function AuthFailureCard({ auth, text, detail, fail
236
238
  })]
237
239
  }) : /* @__PURE__ */ jsxs("div", {
238
240
  className: "flex flex-col gap-1.5",
239
- children: [switching?.error !== void 0 && /* @__PURE__ */ jsx("div", {
240
- role: "alert",
241
- className: "text-zg-danger break-words",
242
- children: labels.authFailed(switching.error)
241
+ children: [switching?.error !== void 0 && /* @__PURE__ */ jsx(Notice, {
242
+ tone: "error",
243
+ compact: true,
244
+ detail: switching.error,
245
+ children: labels.authSignInFailed
243
246
  }), /* @__PURE__ */ jsxs("div", {
244
247
  className: "flex flex-wrap items-center gap-1.5",
245
248
  children: [
@@ -1,6 +1,8 @@
1
+ import { errorMessage } from "../../components/report-error.js";
1
2
  import { RowActionsMenu } from "../../components/RowActionsMenu.js";
2
3
  import { useOptionalChatHost } from "../ChatProvider.js";
3
4
  import { useExtensionsHost } from "../../extensions/ExtensionsProvider.js";
5
+ import { useNotify } from "../../app/NoticeStack.js";
4
6
  import { openInNewTab } from "../../extensions/headless/links.js";
5
7
  import { useLinkRouter } from "../../extensions/links.js";
6
8
  import { extensionsBadgeActions } from "../headless/extension-sources.js";
@@ -67,6 +69,7 @@ function BadgeMenuProvider({ composer, system, browser, children }) {
67
69
  const badges = useOptionalChatHost()?.badges ?? extensionsBadgeActions(extensions);
68
70
  const labels = useChatLabels();
69
71
  const links = useLinkRouter();
72
+ const notify = useNotify();
70
73
  const [open, setOpen] = useState(null);
71
74
  const [notice, setNotice] = useState(null);
72
75
  const seq = useRef(0);
@@ -124,7 +127,14 @@ function BadgeMenuProvider({ composer, system, browser, children }) {
124
127
  return;
125
128
  }
126
129
  (async () => {
127
- const text = await applyBadgeEffect(item.source === "builtin" ? builtinBadgeEffect(item.id, target) ?? {} : await (badges?.run(cwd, item.source, item.id, target) ?? Promise.resolve({})).catch((err) => ({ notice: err instanceof Error ? err.message : String(err) })), {
130
+ const text = await applyBadgeEffect(item.source === "builtin" ? builtinBadgeEffect(item.id, target) ?? {} : await (badges?.run(cwd, item.source, item.id, target) ?? Promise.resolve({})).catch((err) => {
131
+ notify({
132
+ tone: "error",
133
+ message: labels.badgeActionFailed,
134
+ detail: errorMessage(err)
135
+ });
136
+ return {};
137
+ }), {
128
138
  target,
129
139
  cwd,
130
140
  builtin: item.source === "builtin" ? item.id : null,
@@ -148,7 +158,8 @@ function BadgeMenuProvider({ composer, system, browser, children }) {
148
158
  system,
149
159
  browser,
150
160
  labels,
151
- links
161
+ links,
162
+ notify
152
163
  ]);
153
164
  return /* @__PURE__ */ jsxs(BadgeMenuContext.Provider, {
154
165
  value: show,
@@ -1,3 +1,4 @@
1
+ import { Notice } from "../../components/Notice.js";
1
2
  import { CodeFrame } from "../../components/CodeFrame.js";
2
3
  import { useNearViewport } from "../../hooks/useNearViewport.js";
3
4
  import { HighlightedCode } from "../../code/HighlightedCode.js";
@@ -159,9 +160,12 @@ const MermaidDiagram = memo(function MermaidDiagram({ code, streaming = false, c
159
160
  language: "mermaid",
160
161
  className: "mb-1",
161
162
  copyLabel: labels.copyDiagramSource
162
- }), /* @__PURE__ */ jsx("p", {
163
- className: "zg-meta m-0 mb-2 whitespace-pre-wrap",
164
- children: labels.diagramError(failed.message, at)
163
+ }), /* @__PURE__ */ jsx(Notice, {
164
+ tone: "warning",
165
+ compact: true,
166
+ detail: failed.message,
167
+ className: "mb-2",
168
+ children: labels.diagramNotDrawn(at)
165
169
  })]
166
170
  });
167
171
  }
@@ -41,6 +41,10 @@ interface FoldHeaderProps {
41
41
  * a toggle with its caret when opening shows something more, otherwise the
42
42
  * same line, inert. Same box, tone and spacing either way.
43
43
  *
44
+ * One element in both states: swapping a `<div>` for a `<button>` remounted
45
+ * the line's content, so a live fold turning expandable (its 4th step) replayed
46
+ * the enter of everything in it, its elapsed chip popping in again.
47
+ *
44
48
  * @param props - Header props: `expandable`, `open`, `onToggle`, and the `children` of the line.
45
49
  */
46
50
  declare function FoldHeader({ expandable, open, onToggle, children, className, style }: FoldHeaderProps): import("react").JSX.Element;