zidane-ui 9.1.13 → 9.1.14

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 (309) 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 +5 -16
  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 +24 -25
  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 +3 -3
  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/appearance/AppearanceProvider.js +2 -2
  31. package/dist/appearance/headless/index.js +1 -1
  32. package/dist/approvals/headless/index.js +2 -2
  33. package/dist/chat/SessionFilterMenu.d.ts +1 -1
  34. package/dist/chat/SessionFilterMenu.js +2 -1
  35. package/dist/chat/Transcript.js +1 -1
  36. package/dist/chat/composer/Composer.js +9 -6
  37. package/dist/chat/composer/ComposerEditor.js +1 -1
  38. package/dist/chat/composer/ConversationBadges.js +1 -1
  39. package/dist/chat/composer/ModelChainList.js +17 -8
  40. package/dist/chat/composer/ModelChainTooltip.js +5 -2
  41. package/dist/chat/composer/use-composer-stores.js +1 -1
  42. package/dist/chat/composer/use-draft-target.d.ts +20 -1
  43. package/dist/chat/composer/use-draft-target.js +122 -6
  44. package/dist/chat/composer/use-new-session-defaults.d.ts +5 -1
  45. package/dist/chat/composer/use-new-session-defaults.js +17 -4
  46. package/dist/chat/composer/use-run-meter.js +1 -1
  47. package/dist/chat/composer/use-send-prompt.js +1 -1
  48. package/dist/chat/headless/chip-labels.d.ts +1 -0
  49. package/dist/chat/headless/chip-labels.js +1 -0
  50. package/dist/chat/headless/composer/index.js +2 -2
  51. package/dist/chat/headless/draft-target.d.ts +21 -1
  52. package/dist/chat/headless/fixture-host.js +17 -2
  53. package/dist/chat/headless/host.d.ts +3 -3
  54. package/dist/chat/headless/index.d.ts +9 -9
  55. package/dist/chat/headless/index.js +15 -15
  56. package/dist/chat/headless/labels.d.ts +13 -4
  57. package/dist/chat/headless/labels.js +8 -5
  58. package/dist/chat/headless/session-list.d.ts +20 -6
  59. package/dist/chat/headless/session-list.js +1 -0
  60. package/dist/chat/headless/sidebar/directory.d.ts +56 -14
  61. package/dist/chat/headless/sidebar/directory.js +149 -70
  62. package/dist/chat/headless/sidebar/index.d.ts +3 -3
  63. package/dist/chat/headless/sidebar/index.js +3 -3
  64. package/dist/chat/headless/sidebar/labels.d.ts +15 -6
  65. package/dist/chat/headless/sidebar/types.d.ts +3 -1
  66. package/dist/chat/headless/sidebar/view.d.ts +13 -5
  67. package/dist/chat/headless/sidebar/view.js +31 -11
  68. package/dist/chat/headless/streams/actions.d.ts +5 -3
  69. package/dist/chat/headless/streams/actions.js +3 -2
  70. package/dist/chat/headless/streams/index.d.ts +3 -3
  71. package/dist/chat/headless/streams/merge.d.ts +6 -10
  72. package/dist/chat/headless/streams/merge.js +7 -21
  73. package/dist/chat/headless/streams/session-streams.d.ts +29 -4
  74. package/dist/chat/headless/streams/session-streams.js +86 -0
  75. package/dist/chat/headless/streams/store.d.ts +162 -16
  76. package/dist/chat/headless/streams/store.js +334 -38
  77. package/dist/chat/headless/streams/types.d.ts +10 -7
  78. package/dist/chat/headless/transcript-labels.d.ts +1 -0
  79. package/dist/chat/interactions/PlanCard.js +10 -3
  80. package/dist/chat/interactions/QuestionForm.js +7 -3
  81. package/dist/chat/interactions/card-ui.d.ts +5 -3
  82. package/dist/chat/interactions/card-ui.js +9 -7
  83. package/dist/chat/sidebar/SessionSidebar.js +5 -5
  84. package/dist/chat/sidebar/SidebarFilterMenu.js +3 -1
  85. package/dist/chat/sidebar/SidebarFrame.d.ts +4 -0
  86. package/dist/chat/sidebar/SidebarFrame.js +27 -9
  87. package/dist/chat/sidebar/SidebarGroupHeader.js +1 -1
  88. package/dist/chat/sidebar/SidebarHostProvider.d.ts +8 -5
  89. package/dist/chat/sidebar/SidebarHostProvider.js +13 -9
  90. package/dist/chat/sidebar/SidebarToggleButton.js +7 -3
  91. package/dist/chat/sidebar/index.d.ts +2 -2
  92. package/dist/chat/sidebar/session-menu.js +4 -4
  93. package/dist/chat/sidebar/useSaveViewAsSpace.js +2 -2
  94. package/dist/chat/testing/contract.js +2 -2
  95. package/dist/chat/transcript/AuthFailureCard.js +11 -8
  96. package/dist/chat/transcript/BadgeMenu.js +13 -2
  97. package/dist/chat/transcript/MermaidDiagram.js +7 -3
  98. package/dist/chat/transcript/fold.d.ts +4 -0
  99. package/dist/chat/transcript/fold.js +53 -22
  100. package/dist/chat/transcript/script-input.d.ts +1 -1
  101. package/dist/chat/transcript/shell-block.js +8 -4
  102. package/dist/chat/transcript/useStickToBottom.js +12 -0
  103. package/dist/components/BrowserSignIn.js +23 -21
  104. package/dist/components/Form.d.ts +6 -4
  105. package/dist/components/Form.js +16 -8
  106. package/dist/components/LoadError.d.ts +4 -2
  107. package/dist/components/LoadError.js +13 -9
  108. package/dist/components/Notice.d.ts +29 -0
  109. package/dist/components/Notice.js +63 -0
  110. package/dist/components/PanelEmpty.d.ts +1 -1
  111. package/dist/components/PanelEmpty.js +4 -2
  112. package/dist/components/Restricted.d.ts +1 -1
  113. package/dist/components/palette/PaletteList.js +8 -1
  114. package/dist/components/palette/PalettePanel.js +14 -6
  115. package/dist/core.css +24 -5
  116. package/dist/dist/{index-Bq87OcGy.d.ts → index-C6rzc-tt.d.ts} +28 -3
  117. package/dist/dist/index.d.ts +2 -2
  118. package/dist/dist/{timeout-B5pO5I5a.d.ts → timeout-Cz9dRF8Q.d.ts} +1 -1
  119. package/dist/extensions/ExtensionSettingsPage.js +2 -5
  120. package/dist/extensions/ExtensionSettingsSection.js +5 -4
  121. package/dist/extensions/ExtensionSettingsSidebar.js +3 -7
  122. package/dist/extensions/SettingsWireForm.d.ts +1 -7
  123. package/dist/extensions/SettingsWireForm.js +7 -5
  124. package/dist/extensions/headless/fixture-host.d.ts +1 -5
  125. package/dist/extensions/headless/fixture-host.js +2 -5
  126. package/dist/extensions/headless/host.d.ts +1 -11
  127. package/dist/extensions/headless/index.d.ts +3 -3
  128. package/dist/extensions/headless/index.js +6 -6
  129. package/dist/extensions/headless/select.d.ts +1 -11
  130. package/dist/extensions/headless/select.js +1 -18
  131. package/dist/extensions/hooks.js +1 -1
  132. package/dist/files/EditorColumn.js +13 -2
  133. package/dist/files/MediaDiff.js +1 -1
  134. package/dist/files/TreeColumn.js +13 -20
  135. package/dist/files/useEntryActions.js +1 -1
  136. package/dist/files/useOpenFiles.js +3 -1
  137. package/dist/git/BranchMenu.js +6 -4
  138. package/dist/git/ImportRepoDialog.js +18 -9
  139. package/dist/git/MoveSessionDialog.js +16 -8
  140. package/dist/git/RemoteFolderPicker.js +35 -17
  141. package/dist/git/SyncChip.js +17 -17
  142. package/dist/git/WherePicker.d.ts +16 -1
  143. package/dist/git/WherePicker.js +81 -37
  144. package/dist/git/headless/environment.d.ts +33 -3
  145. package/dist/git/headless/environment.js +33 -5
  146. package/dist/git/headless/index.d.ts +2 -2
  147. package/dist/git/headless/index.js +2 -2
  148. package/dist/git/headless/labels.d.ts +15 -2
  149. package/dist/git/headless/labels.js +17 -4
  150. package/dist/git/useEnvironmentChoices.d.ts +3 -1
  151. package/dist/git/useEnvironmentChoices.js +7 -4
  152. package/dist/index.d.ts +2 -1
  153. package/dist/index.js +2 -1
  154. package/dist/keybindings/KeyCommands.js +1 -1
  155. package/dist/keybindings/KeybindingsProvider.js +1 -1
  156. package/dist/keybindings/headless/index.js +2 -2
  157. package/dist/keybindings/headless/overrides.js +1 -1
  158. package/dist/labels.d.ts +5 -0
  159. package/dist/labels.js +5 -0
  160. package/dist/machines/AddMachineDialog.d.ts +34 -0
  161. package/dist/machines/AddMachineDialog.js +464 -0
  162. package/dist/machines/Banners.d.ts +33 -4
  163. package/dist/machines/Banners.js +64 -3
  164. package/dist/machines/DaemonMenu.js +27 -4
  165. package/dist/machines/HostCapabilities.d.ts +1 -3
  166. package/dist/machines/HostCapabilities.js +24 -45
  167. package/dist/machines/HostSyncPanel.js +124 -130
  168. package/dist/machines/HostsSection.d.ts +4 -1
  169. package/dist/machines/HostsSection.js +30 -7
  170. package/dist/machines/MachinesExplainer.d.ts +17 -0
  171. package/dist/machines/MachinesExplainer.js +71 -0
  172. package/dist/machines/MachinesProvider.d.ts +14 -2
  173. package/dist/machines/MachinesProvider.js +35 -1
  174. package/dist/machines/ServerAddedCard.d.ts +31 -0
  175. package/dist/machines/ServerAddedCard.js +72 -0
  176. package/dist/machines/ServerCard.js +91 -215
  177. package/dist/machines/ServerMachinesPanel.d.ts +2 -2
  178. package/dist/machines/ServerMachinesPanel.js +184 -323
  179. package/dist/machines/ServerUpdatePanel.js +51 -40
  180. package/dist/machines/ShareThisComputerForm.d.ts +19 -0
  181. package/dist/machines/ShareThisComputerForm.js +133 -0
  182. package/dist/machines/SyncOutcomeBadge.js +1 -1
  183. package/dist/machines/TokensPanel.d.ts +5 -3
  184. package/dist/machines/TokensPanel.js +98 -78
  185. package/dist/machines/headless/fixture-host.d.ts +19 -3
  186. package/dist/machines/headless/fixture-host.js +43 -6
  187. package/dist/machines/headless/fixtures.js +4 -6
  188. package/dist/machines/headless/host.d.ts +40 -19
  189. package/dist/machines/headless/index.d.ts +3 -3
  190. package/dist/machines/headless/index.js +3 -3
  191. package/dist/machines/headless/labels.d.ts +63 -20
  192. package/dist/machines/headless/labels.js +88 -25
  193. package/dist/machines/headless/messages.js +8 -0
  194. package/dist/machines/headless/stores.d.ts +9 -2
  195. package/dist/machines/headless/stores.js +28 -1
  196. package/dist/machines/index.d.ts +7 -3
  197. package/dist/machines/index.js +8 -4
  198. package/dist/machines/testing/contract.d.ts +15 -3
  199. package/dist/machines/testing/contract.js +68 -14
  200. package/dist/motion/grow.d.ts +8 -1
  201. package/dist/motion/grow.js +10 -4
  202. package/dist/onboarding/headless/labels.d.ts +13 -0
  203. package/dist/onboarding/headless/labels.js +8 -0
  204. package/dist/onboarding/sources/SourceBrowser.js +11 -7
  205. package/dist/onboarding/steps/ImportStep.js +4 -1
  206. package/dist/onboarding/steps/ReadyStep.js +9 -2
  207. package/dist/onboarding/steps/connect/KeyForm.js +6 -2
  208. package/dist/onboarding/steps/connect/ProviderPanel.js +6 -2
  209. package/dist/onboarding/steps/connect/ProviderReady.js +25 -20
  210. package/dist/onboarding/steps/tasks.js +17 -14
  211. package/dist/palette/app-sources.js +1 -1
  212. package/dist/server/sse-handler.js +141 -19
  213. package/dist/session/ArtifactsPanel.js +40 -18
  214. package/dist/session/PlanTracker.js +13 -8
  215. package/dist/session/ProjectHome.js +13 -11
  216. package/dist/session/RemindersPanel.js +35 -17
  217. package/dist/session/RunningWorkDialog.js +6 -2
  218. package/dist/session/SecretsPanel.js +29 -10
  219. package/dist/session/SessionDetailsDialog.d.ts +1 -1
  220. package/dist/session/SessionDetailsDialog.js +18 -10
  221. package/dist/session/SideChat.js +10 -7
  222. package/dist/session/TurnDetailsDialog.js +19 -5
  223. package/dist/session/UsagePanel.js +10 -4
  224. package/dist/session/headless/host.d.ts +2 -0
  225. package/dist/session/headless/index.js +2 -2
  226. package/dist/session/headless/labels.d.ts +19 -1
  227. package/dist/session/headless/labels.js +15 -1
  228. package/dist/session/headless/queue.js +2 -1
  229. package/dist/session/headless/reminder-labels.d.ts +4 -0
  230. package/dist/session/headless/reminder-labels.js +4 -0
  231. package/dist/settings/SettingsRestricted.d.ts +1 -1
  232. package/dist/settings/SettingsRestricted.js +4 -4
  233. package/dist/settings/SettingsShell.d.ts +7 -0
  234. package/dist/settings/SettingsShell.js +6 -1
  235. package/dist/settings/headless/fixture-performance.d.ts +1 -1
  236. package/dist/settings/headless/host.d.ts +2 -2
  237. package/dist/settings/headless/index.js +1 -1
  238. package/dist/settings/headless/labels.d.ts +3 -3
  239. package/dist/settings/headless/labels.js +3 -3
  240. package/dist/settings/headless/performance.d.ts +3 -4
  241. package/dist/settings/headless/search.d.ts +1 -1
  242. package/dist/settings/index.d.ts +2 -1
  243. package/dist/settings/index.js +2 -1
  244. package/dist/settings/sections/appearance/AppearanceSection.js +2 -2
  245. package/dist/settings/sections/claude-import/ClaudeImportDialog.js +1 -1
  246. package/dist/settings/sections/editor/EditorSection.js +8 -5
  247. package/dist/settings/sections/editor/labels.d.ts +1 -0
  248. package/dist/settings/sections/editor/labels.js +1 -0
  249. package/dist/settings/sections/environments/EnvironmentsSection.js +21 -14
  250. package/dist/settings/sections/environments/labels.d.ts +1 -0
  251. package/dist/settings/sections/environments/labels.js +2 -1
  252. package/dist/settings/sections/extensions/ChangeOriginDialog.js +1 -1
  253. package/dist/settings/sections/extensions/CreateExtensionDialog.js +1 -1
  254. package/dist/settings/sections/extensions/ExtensionConfigRows.d.ts +1 -3
  255. package/dist/settings/sections/extensions/ExtensionConfigRows.js +20 -19
  256. package/dist/settings/sections/extensions/ExtensionOptionsSection.js +2 -1
  257. package/dist/settings/sections/extensions/ExtensionsSection.js +1 -1
  258. package/dist/settings/sections/extensions/options-labels.d.ts +2 -1
  259. package/dist/settings/sections/extensions/options-labels.js +2 -1
  260. package/dist/settings/sections/host-catalog/HostCatalogSection.js +1 -1
  261. package/dist/settings/sections/index.d.ts +2 -1
  262. package/dist/settings/sections/index.js +2 -1
  263. package/dist/settings/sections/instructions/InstructionsSection.js +1 -1
  264. package/dist/settings/sections/logs/LogsSection.d.ts +2 -2
  265. package/dist/settings/sections/logs/LogsSection.js +2 -2
  266. package/dist/settings/sections/mcp/McpSection.d.ts +1 -1
  267. package/dist/settings/sections/mcp/McpSection.js +13 -7
  268. package/dist/settings/sections/mcp/McpServerRow.js +21 -14
  269. package/dist/settings/sections/mcp/labels.d.ts +8 -2
  270. package/dist/settings/sections/mcp/labels.js +8 -2
  271. package/dist/settings/sections/models/ModelRows.js +1 -1
  272. package/dist/settings/sections/models/NewChatPlaceRow.d.ts +26 -0
  273. package/dist/settings/sections/models/NewChatPlaceRow.js +78 -0
  274. package/dist/settings/sections/models/SpacesDefaultsSection.js +15 -3
  275. package/dist/settings/sections/models/labels.d.ts +7 -0
  276. package/dist/settings/sections/models/labels.js +7 -0
  277. package/dist/settings/sections/models/model-test.js +7 -4
  278. package/dist/settings/sections/performance/PerformanceSection.js +16 -6
  279. package/dist/settings/sections/performance/labels.d.ts +1 -1
  280. package/dist/settings/sections/performance/labels.js +1 -1
  281. package/dist/settings/sections/providers/ProvidersSection.d.ts +1 -1
  282. package/dist/settings/sections/providers/ProvidersSection.js +15 -8
  283. package/dist/settings/sections/providers/ServerProvidersSection.d.ts +1 -1
  284. package/dist/settings/sections/providers/ServerProvidersSection.js +12 -6
  285. package/dist/settings/sections/providers/labels.d.ts +2 -2
  286. package/dist/settings/sections/providers/labels.js +2 -2
  287. package/dist/settings/sections/shared/catalog.js +1 -1
  288. package/dist/settings/sections/skills/SkillsSection.js +1 -1
  289. package/dist/settings/testing/performance.contract.js +8 -12
  290. package/dist/styles.css +32 -3
  291. package/dist/terminal/HostTerminalSurface.js +17 -7
  292. package/dist/terminal/TerminalPanel.js +30 -17
  293. package/dist/terminal/TerminalSurface.js +11 -4
  294. package/dist/terminal/headless/labels.d.ts +5 -0
  295. package/dist/terminal/headless/labels.js +5 -0
  296. package/dist/terminal/headless/store.d.ts +1 -1
  297. package/dist/terminal/headless/store.js +6 -3
  298. package/dist/workspace/LayoutBudget.d.ts +5 -1
  299. package/dist/workspace/LayoutBudget.js +14 -1
  300. package/dist/workspace/PanelContentView.d.ts +1 -1
  301. package/dist/workspace/PanelContentView.js +17 -6
  302. package/dist/workspace/WorkspaceProvider.js +4 -3
  303. package/dist/workspace/extension-tabs.js +1 -1
  304. package/dist/workspace/headless/index.js +1 -1
  305. package/dist/workspace/headless/labels.d.ts +1 -0
  306. package/dist/workspace/headless/labels.js +1 -0
  307. package/package.json +3 -3
  308. package/src/styles/motion.css +8 -0
  309. package/src/styles/primitives.css +7 -0
@@ -1,20 +1,20 @@
1
- import { closableClient } from "./closable-client.js";
2
1
  import { machinesError } from "../machines/headless/host.js";
3
- import { createPresenceStore } from "../machines/headless/presence.js";
4
2
  import { createMachineLists, createOnlineMachines, lazyReadable } from "../machines/headless/stores.js";
3
+ import { closableClient } from "./closable-client.js";
4
+ import { createPresenceStore } from "../machines/headless/presence.js";
5
5
  import { createHostSyncReads } from "../machines/headless/sync.js";
6
6
  import { serverOAuthFlow } from "./server-oauth-flow.js";
7
- import { IpcErrorCode, formatJoinString } from "zidane/ipc/browser";
7
+ import { formatJoinString } from "zidane/ipc/browser";
8
8
  //#region src/adapters/server-machines-host.ts
9
9
  /**
10
10
  * A `MachinesHost` on a running zidane-server, over a shared browser client
11
11
  * (`createServerClient`), for a web app the server serves: the one server it
12
- * talks to (from the client's state and the handshake: name, version, the
13
- * token's scope, uptime), its machines (`machines.list`, `machines.forget`,
12
+ * talks to (from the client's state and the handshake: name, version,
13
+ * uptime), its machines (`machines.list`, `machines.forget`,
14
14
  * kept current by the `machine:status` signal and re-read after every
15
15
  * handshake; `tokens.machineInvite` makes a join code when the server's
16
16
  * `url` is given), its self-update (`server.update.*`), its client tokens
17
- * (`tokens.list` / `create` / `revoke`, re-read on `tokens:changed`), what it can do (`host.capabilities`)
17
+ * (`tokens.list` / `create` / `revoke` / `pair`, re-read on `tokens:changed`), what it can do (`host.capabilities`)
18
18
  * and per-session presence
19
19
  * (`presence.list`, kept current by `presence:changed`, re-listed after every
20
20
  * handshake). Of settings sync, the server's side: its record
@@ -23,10 +23,9 @@ import { IpcErrorCode, formatJoinString } from "zidane/ipc/browser";
23
23
  * override (`sync.reset`), its providers (`auth.status`) and a sign-in there
24
24
  * (`auth.oauth.*`, `serverOAuthFlow`).
25
25
  *
26
- * What a token may do comes from the handshake (`client.can`), in
27
- * `permitted`: a `chat` or `approve` token lists machines and reads the
28
- * update status, only an `admin` one forgets machines, runs updates and
29
- * manages tokens. The components hide what is not permitted.
26
+ * What the server offers comes from the handshake (`client.can`), in
27
+ * `permitted`. It is `null` until the handshake lands. The components hide
28
+ * what is not permitted.
30
29
  *
31
30
  * A store it hands out may listen to the client for good (who is online):
32
31
  * `close()` stops every listener.
@@ -37,8 +36,6 @@ import { IpcErrorCode, formatJoinString } from "zidane/ipc/browser";
37
36
  * machine `links`, `pickFolder`, the local `daemon`, and this computer's sync
38
37
  * engine (`sync.state`, `configure`, `push`, `takeOver`: a browser is not a device
39
38
  * that pushes its settings; `sync.claim` / `sync.push` are a device's calls).
40
- * `sync.*` needs an admin token: below it the record reads `null` and a reset
41
- * rejects.
42
39
  */
43
40
  /** The id the server goes by until its handshake names it (`hello.hostId`). */
44
41
  const SERVER_MACHINES_HOST_ID = "server";
@@ -68,7 +65,7 @@ function createServerMachinesHost(options) {
68
65
  if (state.status === "open" && !wasOpen) lastConnectedAt = Date.now();
69
66
  wasOpen = state.status === "open";
70
67
  everOpen ||= wasOpen;
71
- const status = state.status === "open" ? "connected" : state.status === "connecting" ? everOpen ? "reconnecting" : "connecting" : state.status === "retrying" ? "reconnecting" : state.status === "refused" ? state.reason === "protocol" ? "version-mismatch" : state.reason === "token" || state.reason === "scope" ? "auth-refused" : "offline" : "offline";
68
+ const status = state.status === "open" ? "connected" : state.status === "connecting" ? everOpen ? "reconnecting" : "connecting" : state.status === "retrying" ? "reconnecting" : state.status === "refused" ? state.reason === "protocol" ? "version-mismatch" : state.reason === "token" ? "auth-refused" : "offline" : "offline";
72
69
  const error = state.status === "retrying" ? state.error : state.status === "refused" ? state.message : void 0;
73
70
  return {
74
71
  id: hello?.hostId ?? "server",
@@ -77,8 +74,6 @@ function createServerMachinesHost(options) {
77
74
  status,
78
75
  ...error ? { error } : {},
79
76
  ...hello?.appVersion ? { serverVersion: hello.appVersion } : {},
80
- ...hello?.scope ? { scope: hello.scope === "admin" ? "admin" : "chat" } : {},
81
- ...hello?.adminCommands ? { adminCommands: hello.adminCommands } : {},
82
77
  ...hello?.startedAt ? { startedAt: hello.startedAt } : {},
83
78
  ...hello?.machineServe ? { machineServe: true } : {},
84
79
  ...lastConnectedAt ? { lastConnectedAt } : {}
@@ -117,9 +112,13 @@ function createServerMachinesHost(options) {
117
112
  }, (onChange) => {
118
113
  const offStatus = onMachineStatus(() => onChange(SERVER_MACHINES_HOST_ID));
119
114
  const offOpen = client.onOpen(() => onChange(SERVER_MACHINES_HOST_ID));
115
+ const offChanged = client.onSignal((signal) => {
116
+ if (signal.kind === "machine:changed") onChange(SERVER_MACHINES_HOST_ID);
117
+ });
120
118
  return () => {
121
119
  offStatus();
122
120
  offOpen();
121
+ offChanged();
123
122
  };
124
123
  });
125
124
  const syncStatus = createHostSyncReads(() => client.call("sync.status", {}), (onChange) => {
@@ -141,9 +140,15 @@ function createServerMachinesHost(options) {
141
140
  };
142
141
  return {
143
142
  hosts,
143
+ ...options.newChat ? { newChat: options.newChat } : {},
144
144
  machines: {
145
145
  list: () => lists(SERVER_MACHINES_HOST_ID),
146
146
  online: createOnlineMachines(onMachineStatus),
147
+ onJoin: (_hostId, listener) => client.onSignal((signal) => {
148
+ if (signal.kind !== "machine:join") return;
149
+ const { kind: _kind, ...event } = signal;
150
+ listener(event);
151
+ }),
147
152
  forget: (_hostId, machineId) => guard("forget", async () => {
148
153
  await client.call("machines.forget", { machineId });
149
154
  }),
@@ -153,14 +158,10 @@ function createServerMachinesHost(options) {
153
158
  return {
154
159
  code,
155
160
  expiresAt,
156
- join: formatJoinString(serverUrl, code)
161
+ join: formatJoinString(client.hello()?.clientUrl ?? serverUrl, code)
157
162
  };
158
163
  } catch (error) {
159
- const forbidden = error?.code === IpcErrorCode.Forbidden;
160
- throw {
161
- ...machinesError("invite", error),
162
- ...forbidden ? { forbidden } : {}
163
- };
164
+ throw machinesError("invite", error);
164
165
  }
165
166
  } } : {}
166
167
  },
@@ -172,10 +173,8 @@ function createServerMachinesHost(options) {
172
173
  },
173
174
  tokens: {
174
175
  list: (_hostId) => guard("tokens", () => client.call("tokens.list", {})),
175
- create: (_hostId, name, scope) => guard("tokens", () => client.call("tokens.create", {
176
- name,
177
- scope
178
- })),
176
+ create: (_hostId, name) => guard("tokens", () => client.call("tokens.create", { name })),
177
+ pair: (_hostId, params = {}) => guard("tokens", () => client.call("tokens.pair", params)),
179
178
  revoke: (_hostId, id) => guard("tokens", async () => {
180
179
  await client.call("tokens.revoke", { id });
181
180
  }),
@@ -19,7 +19,7 @@ interface ServerOnboardingHostOptions {
19
19
  /** The folder on the server whose extension providers and catalog count. Absent: the server user's scope. */
20
20
  cwd?: string;
21
21
  /**
22
- * `false` leaves out keys, sign-ins, connectors and extensions, for a token without the `admin` scope.
22
+ * `false` leaves out keys, sign-ins, connectors and extensions.
23
23
  * Default: `client.can('auth.setApiKey')` once the handshake has landed, `true` before it.
24
24
  */
25
25
  canConfigure?: boolean;
@@ -20,10 +20,9 @@ import { CONNECTORS, connectorById, connectorInstalled, connectorServerConfig, n
20
20
  * without it). The look is the page's: pass `themes` and `appIcons` to offer
21
21
  * Look, and `onCommitted` to apply what a run picked for this page.
22
22
  *
23
- * Reading needs a `chat` token. Keys, sign-ins, installs and the write need
24
- * `admin`. Built after the handshake (`await client.ready`), the host follows
25
- * the token: with a lesser one, Connect lists the providers and installs and
26
- * keys are left out.
23
+ * Built after the handshake (`await client.ready`). Keys, sign-ins and
24
+ * installs show when the server's hello lists `auth.setApiKey`
25
+ * (`canConfigure`).
27
26
  *
28
27
  * When the handshake lists them: what zidane finds on the server's machine
29
28
  * (`onboarding.detect`: other agents, local model servers, the GitHub
@@ -217,9 +217,28 @@ function createServerSessionHost(options) {
217
217
  if (await client.call("chat.isRunning", { sessionId: sideId })) await client.call("chat.interrupt", { sessionId: sideId });
218
218
  await client.call("sessions.delete", { sessionId: sideId });
219
219
  },
220
- subscribe: (onChange) => client.onSignal((signal) => {
221
- if (signal.kind === "sessions:changed" && signal.op === "update") onChange(signal.sessionId);
222
- })
220
+ subscribe: (onChange) => {
221
+ const picks = /* @__PURE__ */ new Map();
222
+ return client.onSignal((signal) => {
223
+ if (signal.kind !== "sessions:changed") return;
224
+ if (signal.op === "delete") {
225
+ picks.delete(signal.sessionId);
226
+ return;
227
+ }
228
+ const { row } = signal;
229
+ const pick = JSON.stringify([
230
+ row.providerKey,
231
+ row.modelId,
232
+ row.effort,
233
+ row.modelOptions,
234
+ row.account,
235
+ row.agentId
236
+ ]);
237
+ const before = picks.get(signal.sessionId);
238
+ picks.set(signal.sessionId, pick);
239
+ if (signal.op === "update" && before !== pick) onChange(signal.sessionId);
240
+ });
241
+ }
223
242
  } } : {},
224
243
  ...client.can("secrets.list") ? { secrets: {
225
244
  entries: secrets.entries,
@@ -1,11 +1,11 @@
1
1
  import { serverOAuthFlow } from "./server-oauth-flow.js";
2
2
  import { createSettingsResource, keyedSettingsResources } from "../settings/headless/resource.js";
3
3
  import { settingsMcpServerOf } from "../settings/headless/mcp.js";
4
- import { IpcErrorCode, ServerCallError, ServerConnectionError } from "zidane/ipc/browser";
4
+ import { ServerConnectionError } from "zidane/ipc/browser";
5
5
  //#region src/adapters/server-settings-accounts.ts
6
6
  const errorOf = (error) => {
7
7
  const detail = error instanceof Error ? error.message : void 0;
8
- const kind = error instanceof ServerConnectionError ? "unreachable" : error instanceof ServerCallError && error.code === IpcErrorCode.Forbidden ? "refused" : "failed";
8
+ const kind = error instanceof ServerConnectionError ? "unreachable" : "failed";
9
9
  return detail ? {
10
10
  kind,
11
11
  detail
@@ -1,15 +1,15 @@
1
1
  import { writable } from "../chat/headless/store.js";
2
- import { closableClient } from "./closable-client.js";
3
2
  import { DEFAULT_SETTINGS } from "../settings/headless/catalog.js";
3
+ import { closableClient } from "./closable-client.js";
4
4
  import { serverSettingsSections } from "./server-settings-sections.js";
5
5
  import { serverSettingsAccounts } from "./server-settings-accounts.js";
6
6
  import { serverSettingsModels } from "./server-settings-models.js";
7
7
  import { serverSettingsPerformance } from "./server-settings-performance.js";
8
- import { IpcErrorCode, ServerCallError, ServerConnectionError } from "zidane/ipc/browser";
8
+ import { ServerConnectionError } from "zidane/ipc/browser";
9
9
  //#region src/adapters/server-settings-host.ts
10
10
  const errorOf = (error) => {
11
11
  const detail = error instanceof Error ? error.message : void 0;
12
- const kind = error instanceof ServerConnectionError ? "unreachable" : error instanceof ServerCallError && error.code === IpcErrorCode.Forbidden ? "refused" : "failed";
12
+ const kind = error instanceof ServerConnectionError ? "unreachable" : "failed";
13
13
  return detail ? {
14
14
  kind,
15
15
  detail
@@ -1,24 +1,22 @@
1
- import { IpcErrorCode, ServerCallError } from "zidane/ipc/browser";
1
+ import { ServerCallError } from "zidane/ipc/browser";
2
2
  //#region src/adapters/server-settings-performance.ts
3
3
  /**
4
4
  * The performance group of the zidane-server `SettingsHost`
5
5
  * (`createServerSettingsHost`), over the shared browser client: the
6
- * server's own figures (`perf.*`, admin), its samples held
6
+ * server's own figures (`perf.*`), its samples held
7
7
  * (`perf.history`), followed while shown (`perf.watch`, `perf:sample`;
8
8
  * watched again after a reconnect) and a listed process's threads
9
- * (`perf.threads`). Offered when the token reaches them; a server too old
10
- * for them or a chat token has none, and the page says it is not available.
9
+ * (`perf.threads`). Offered when the server has them; a server too old
10
+ * for them has none, and the page says it is not available.
11
11
  * No counters, report or profiles: a server keeps none.
12
12
  */
13
13
  /** JSON-RPC's "method not found": a server older than `perf.*`. */
14
14
  const METHOD_NOT_FOUND = -32601;
15
15
  const watchErrorOf = (error) => {
16
- const code = error instanceof ServerCallError ? error.code : void 0;
17
- if (code === METHOD_NOT_FOUND) return { kind: "unavailable" };
18
- const detail = error instanceof Error ? error.message : String(error);
16
+ if ((error instanceof ServerCallError ? error.code : void 0) === METHOD_NOT_FOUND) return { kind: "unavailable" };
19
17
  return {
20
- kind: code === IpcErrorCode.Forbidden ? "refused" : "failed",
21
- detail
18
+ kind: "failed",
19
+ detail: error instanceof Error ? error.message : String(error)
22
20
  };
23
21
  };
24
22
  /**
@@ -1,31 +1,30 @@
1
1
  import { createSettingsResource, keyedSettingsResources } from "../settings/headless/resource.js";
2
- import { IpcErrorCode, ServerCallError, ServerConnectionError, extensionInstallErrorData } from "zidane/ipc/browser";
2
+ import { ServerCallError, ServerConnectionError, extensionInstallErrorData } from "zidane/ipc/browser";
3
3
  //#region src/adapters/server-settings-sections.ts
4
4
  /**
5
5
  * The catalog and diagnostics groups of the zidane-server `SettingsHost`
6
6
  * (`createServerSettingsHost`), over the shared browser client:
7
7
  *
8
- * - `environments`: `environments.list` / `.update` (admin) / `.verify`.
9
- * - `instructions`: `sessions.contextSegments`, `sessions.createSystemOverride` (admin).
8
+ * - `environments`: `environments.list` / `.update` / `.verify`.
9
+ * - `instructions`: `sessions.contextSegments`, `sessions.createSystemOverride`.
10
10
  * - `hostCatalog`: `catalog.skills|mcps|extensions|plugins`, kept current by
11
- * `catalog:changed`; installs (`catalog.install|remove|update`, admin)
12
- * when the server takes them (`remoteInstalls` on its hello) and the
13
- * token reaches them; the extensions' source browser (`extensions.browse`)
14
- * and a change of origin (`extensions.changeOrigin`, admin, when the
15
- * server takes installs). Its MCP servers are the accounts' `mcp` group.
11
+ * `catalog:changed`; installs (`catalog.install|remove|update`)
12
+ * when the server takes them (`remoteInstalls` on its hello); the
13
+ * extensions' source browser (`extensions.browse`) and a change of origin
14
+ * (`extensions.changeOrigin`, when the server takes installs). Its MCP servers are the accounts' `mcp` group.
16
15
  *
17
16
  * - `extensions`: the server's extensions (`catalog.extensions`), a source's
18
17
  * extensions (`extensions.browse`), a user-scope extension installed
19
- * again from another source (`extensions.changeOrigin`, admin, when the
18
+ * again from another source (`extensions.changeOrigin`, when the
20
19
  * server takes installs), the options and action rows their folder declares
21
20
  * (`extensions.configSchema` / `actions`, refetched on `catalog:changed`),
22
21
  * the actions' probes (`extensions.actionStatuses`), a run
23
- * (`extensions.runAction`, admin) and a scaffold (`extensions.create`,
24
- * admin, when the server takes installs; a project one inside the server's
22
+ * (`extensions.runAction`) and a scaffold (`extensions.create`, when the
23
+ * server takes installs; a project one inside the server's
25
24
  * workspace roots).
26
25
  * - `claudeImport`: the server's `~/.claude` (`claudeImport.detect` / `run`,
27
- * admin, when the server takes installs).
28
- * - `logs`: the server's log (`logs.list`, admin), followed while shown
26
+ * when the server takes installs).
27
+ * - `logs`: the server's log (`logs.list`), followed while shown
29
28
  * (`logs.watch`, `logs:record`; watched again after a reconnect).
30
29
  *
31
30
  * Left out, as the protocol has no method for them: the local-disk
@@ -36,7 +35,7 @@ import { IpcErrorCode, ServerCallError, ServerConnectionError, extensionInstallE
36
35
  */
37
36
  const errorOf = (error) => {
38
37
  const detail = error instanceof Error ? error.message : void 0;
39
- const kind = error instanceof ServerConnectionError ? "unreachable" : error instanceof ServerCallError && error.code === IpcErrorCode.Forbidden ? "refused" : "failed";
38
+ const kind = error instanceof ServerConnectionError ? "unreachable" : "failed";
40
39
  const found = error instanceof ServerCallError ? extensionInstallErrorData(error.data)?.candidates : void 0;
41
40
  return {
42
41
  kind,
@@ -2,8 +2,8 @@ import { ARTIFACT_BADGES_MAX } from "zidane/chat/pure";
2
2
  //#region src/adapters/server-sidebar-host.ts
3
3
  /**
4
4
  * A `SidebarHost` on a running zidane-server: a session's environment
5
- * commands (`sessions.environmentActions`, `sessions.runEnvironmentAction`,
6
- * which needs an `admin` token), setting a failed environment up again
5
+ * commands (`sessions.environmentActions`, `sessions.runEnvironmentAction`),
6
+ * setting a failed environment up again
7
7
  * (`sessions.retryEnvironment`) and, when the handshake lists it, the rows'
8
8
  * badges (`artifacts.badges`, read again on a session's `artifact:recorded` /
9
9
  * `artifact:changed` and on `catalog:changed` for extensions).
@@ -3,6 +3,8 @@ import { createLiveState } from "./live.js";
3
3
  import { createSseParser } from "./sse-parser.js";
4
4
  import { SSE_PROTOCOL_HEADER } from "./sse-protocol.js";
5
5
  //#region src/adapters/sse-host.ts
6
+ /** Reads of a transcript older than its window before a hydrate gives up (see `hydrate`). */
7
+ const HYDRATE_ATTEMPTS = 4;
6
8
  /**
7
9
  * Creates a {@link ChatHost} over HTTP and server-sent events, talking to a handler from {@link createSseHandler}. Actions are POSTs and each watched transcript is one streaming GET that resumes after a drop.
8
10
  *
@@ -15,7 +17,7 @@ function createSseHost(options) {
15
17
  const streams = /* @__PURE__ */ new Map();
16
18
  const headers = async (extra) => {
17
19
  const h = new Headers(typeof options.headers === "function" ? await options.headers() : options.headers);
18
- h.set(SSE_PROTOCOL_HEADER, String(1));
20
+ h.set(SSE_PROTOCOL_HEADER, String(2));
19
21
  for (const [k, v] of Object.entries(extra ?? {})) h.set(k, v);
20
22
  return h;
21
23
  };
@@ -43,16 +45,71 @@ function createSseHost(options) {
43
45
  lingering.delete(sessionId);
44
46
  streams.get(sessionId)?.abort();
45
47
  streams.delete(sessionId);
48
+ stopRereadRetry(sessionId);
46
49
  }, 1e3));
47
50
  }
48
51
  });
49
- const hydrate = async (sessionId) => {
52
+ /**
53
+ * Reads the session's transcript into its window. If the read is older than a write the window applied since, it
54
+ * is read again. The first retry is at once, and each later one waits longer, up to four reads in all. So a server
55
+ * that keeps answering older is not asked in a loop. Then the caller's error path takes over (a stream retries on
56
+ * its own schedule).
57
+ */
58
+ const hydrate = async (sessionId, attempt = 0) => {
50
59
  const h = await request("GET", `/sessions/${sid(sessionId)}/events`);
51
- state.hydrate(sessionId, h.events, { running: h.running });
60
+ if (!state.hydrate(sessionId, h.events, { running: h.running }, h.pos, h.historyId)) {
61
+ if (attempt + 1 >= HYDRATE_ATTEMPTS) throw new Error(`GET /sessions/${sessionId}/events: older than the transcript on show`);
62
+ const wait = attempt === 0 ? 0 : Math.min((options.reconnectMs ?? 500) * 2 ** (attempt - 1), 1e4);
63
+ if (wait > 0) await new Promise((resolve) => setTimeout(resolve, wait));
64
+ return hydrate(sessionId, attempt + 1);
65
+ }
52
66
  for (const i of state.pending(sessionId).get()) state.resolveInteraction(i.requestId);
53
67
  for (const i of h.interactions) state.addInteraction(sessionId, i.request);
54
68
  return h.cursor;
55
69
  };
70
+ /**
71
+ * Reads a transcript again (a rewrite, a missed write, a run's end). One read per session is in flight. A read
72
+ * asked for while another runs is made when the first ends, if the first did not bring the window up to date (it
73
+ * failed, or a write asked for rows it lacks). If a read failed and nothing else asks, it is retried with the
74
+ * stream's backoff while the session is streamed and its rows are still behind. The stream resumes from its last
75
+ * id, so it does not read the transcript again before the session's next write.
76
+ */
77
+ const rereads = /* @__PURE__ */ new Map();
78
+ const rereadRetries = /* @__PURE__ */ new Map();
79
+ const reread = (sessionId, failures = rereadRetries.get(sessionId)?.failures ?? 0) => {
80
+ const inFlight = rereads.get(sessionId);
81
+ if (inFlight) {
82
+ inFlight.again = true;
83
+ return;
84
+ }
85
+ clearTimeout(rereadRetries.get(sessionId)?.timer);
86
+ rereadRetries.delete(sessionId);
87
+ const entry = { again: false };
88
+ rereads.set(sessionId, entry);
89
+ let failed = false;
90
+ hydrate(sessionId).catch((error) => {
91
+ failed = true;
92
+ onError(error);
93
+ }).finally(() => {
94
+ rereads.delete(sessionId);
95
+ if (!state.tailDue(sessionId)) return;
96
+ if (entry.again) return reread(sessionId);
97
+ if (!failed || !streams.has(sessionId)) return;
98
+ const wait = Math.min((options.reconnectMs ?? 500) * 2 ** failures, 1e4);
99
+ const timer = setTimeout(() => {
100
+ rereadRetries.delete(sessionId);
101
+ if (streams.has(sessionId)) reread(sessionId, failures + 1);
102
+ }, wait);
103
+ rereadRetries.set(sessionId, {
104
+ timer,
105
+ failures: failures + 1
106
+ });
107
+ });
108
+ };
109
+ const stopRereadRetry = (sessionId) => {
110
+ clearTimeout(rereadRetries.get(sessionId)?.timer);
111
+ rereadRetries.delete(sessionId);
112
+ };
56
113
  const onRecord = (sessionId, record) => {
57
114
  switch (record.type) {
58
115
  case "event":
@@ -60,6 +117,7 @@ function createSseHost(options) {
60
117
  return true;
61
118
  case "run":
62
119
  state.setRunning(sessionId, record.data.running, record.data.running ? void 0 : record.data.ok === false ? "error" : "completed");
120
+ if (!record.data.running && state.takeRefetchDue(sessionId)) reread(sessionId);
63
121
  return true;
64
122
  case "interaction":
65
123
  state.addInteraction(sessionId, record.data.request);
@@ -70,7 +128,11 @@ function createSseHost(options) {
70
128
  case "session":
71
129
  upsert(record.data.session);
72
130
  return true;
131
+ case "history":
132
+ if (state.applyHistory(sessionId, record.data)) reread(sessionId);
133
+ return true;
73
134
  case "reset": return false;
135
+ default: return true;
74
136
  }
75
137
  };
76
138
  const open = async (sessionId) => {
@@ -160,6 +222,7 @@ function createSseHost(options) {
160
222
  lingering.delete(sessionId);
161
223
  streams.get(sessionId)?.abort();
162
224
  streams.delete(sessionId);
225
+ stopRereadRetry(sessionId);
163
226
  sessions.set((all) => all.filter((s) => s.id !== sessionId));
164
227
  }
165
228
  },
@@ -210,6 +273,8 @@ function createSseHost(options) {
210
273
  lingering.clear();
211
274
  for (const c of streams.values()) c.abort();
212
275
  streams.clear();
276
+ for (const { timer } of rereadRetries.values()) clearTimeout(timer);
277
+ rereadRetries.clear();
213
278
  }
214
279
  };
215
280
  }
@@ -1,8 +1,11 @@
1
1
  import { ChatEvent, ChatInteraction, ChatSession, SendInput } from "../chat/headless/host.js";
2
+ import { HistoryChange } from "zidane/chat/pure";
2
3
  import { InteractionRequest, InteractionResponse } from "zidane/chat";
3
4
  //#region src/adapters/sse-protocol.d.ts
4
5
  /** Version of the HTTP and server-sent-events protocol between {@link createSseHost} and {@link createSseHandler}. */
5
- declare const SSE_PROTOCOL_VERSION = 1;
6
+ declare const SSE_PROTOCOL_VERSION = 2;
7
+ /** The first protocol version whose clients take `history` records. */
8
+ declare const SSE_HISTORY_RECORDS_VERSION = 2;
6
9
  /** Name of the response header that carries the protocol version. */
7
10
  declare const SSE_PROTOCOL_HEADER = "X-Zidane-Chat-Protocol";
8
11
  /** Body of `GET /sessions/:id/events`: the transcript so far, plus what a client needs to start streaming. */
@@ -15,6 +18,10 @@ interface HydrateResponse {
15
18
  cursor: string;
16
19
  /** Requests from the agent that still wait for an answer. */
17
20
  interactions: ChatInteraction[];
21
+ /** The history position the events are at. A `history` record at or below it is in them already. Absent when unknown. */
22
+ pos?: number;
23
+ /** The numbering `pos` counts in (`HistoryPosition.historyId`). */
24
+ historyId?: string;
18
25
  }
19
26
  /** Body of `POST /sessions/:id/send`. */
20
27
  interface SendBody {
@@ -56,6 +63,9 @@ type StreamRecord = {
56
63
  data: {
57
64
  session: ChatSession;
58
65
  };
66
+ } | {
67
+ type: 'history';
68
+ data: HistoryChange;
59
69
  } | {
60
70
  type: 'reset';
61
71
  data: Record<string, never>;
@@ -98,4 +108,4 @@ declare function attachmentsFromPreviews(attachments: SendBody['attachments']):
98
108
  name?: string;
99
109
  }[];
100
110
  //#endregion
101
- export { AnswerBody, HydrateResponse, SSE_PROTOCOL_HEADER, SSE_PROTOCOL_VERSION, SendBody, StreamRecord, attachmentsFromPreviews, encodeSseRecord, formatCursor, parseCursor };
111
+ export { AnswerBody, HydrateResponse, SSE_HISTORY_RECORDS_VERSION, SSE_PROTOCOL_HEADER, SSE_PROTOCOL_VERSION, SendBody, StreamRecord, attachmentsFromPreviews, encodeSseRecord, formatCursor, parseCursor };
@@ -1,6 +1,8 @@
1
1
  //#region src/adapters/sse-protocol.ts
2
2
  /** Version of the HTTP and server-sent-events protocol between {@link createSseHost} and {@link createSseHandler}. */
3
- const SSE_PROTOCOL_VERSION = 1;
3
+ const SSE_PROTOCOL_VERSION = 2;
4
+ /** The first protocol version whose clients take `history` records. */
5
+ const SSE_HISTORY_RECORDS_VERSION = 2;
4
6
  /** Name of the response header that carries the protocol version. */
5
7
  const SSE_PROTOCOL_HEADER = "X-Zidane-Chat-Protocol";
6
8
  /**
@@ -53,4 +55,4 @@ function attachmentsFromPreviews(attachments) {
53
55
  });
54
56
  }
55
57
  //#endregion
56
- export { SSE_PROTOCOL_HEADER, SSE_PROTOCOL_VERSION, attachmentsFromPreviews, encodeSseRecord, formatCursor, parseCursor };
58
+ export { SSE_HISTORY_RECORDS_VERSION, SSE_PROTOCOL_HEADER, SSE_PROTOCOL_VERSION, attachmentsFromPreviews, encodeSseRecord, formatCursor, parseCursor };
@@ -3,6 +3,7 @@ import { ApprovalsProvider } from "../approvals/ApprovalsProvider.js";
3
3
  import { ChatProvider } from "../chat/ChatProvider.js";
4
4
  import { ComposerHostProvider } from "../chat/composer/ComposerHostProvider.js";
5
5
  import { ExtensionsProvider } from "../extensions/ExtensionsProvider.js";
6
+ import { NoticeStackProvider } from "./NoticeStack.js";
6
7
  import { SidebarHostProvider } from "../chat/sidebar/SidebarHostProvider.js";
7
8
  import { FilesProvider } from "../files/FilesProvider.js";
8
9
  import { GitProvider } from "../git/GitProvider.js";
@@ -30,7 +31,7 @@ import { createContext, useContext } from "react";
30
31
  * `SessionProvider` when `host.session` is, `ApprovalsProvider` when
31
32
  * `host.approvals` is, `ExtensionsProvider` when `host.extensions` is, `FilesProvider` when `host.files` is, `GitProvider` when `host.git` is, `MachinesProvider` when `host.machines` is, `SettingsProvider` when `host.settings` is, `TerminalProvider` when `host.terminal` is, `KeybindingsProvider` when `host.keybindings` is and
32
33
  * `AppearanceProvider` when `host.appearance` is, and always a `KeyCommandsProvider` (the key command
33
- * registry: register shortcuts with `useKeyCommands`). `host.workspace` goes in
34
+ * registry: register shortcuts with `useKeyCommands`) and a `NoticeStackProvider` (`useNotify`). `host.workspace` goes in
34
35
  * context for each `WorkspaceProvider` below (`WorkspaceHostProvider`), and
35
36
  * `host.onboarding` for each `OnboardingProvider` below (`OnboardingHostProvider`), `host.composer`
36
37
  * for each rich composer below (`ComposerHostProvider`), `host.sidebar` for the
@@ -109,11 +110,11 @@ function AppHostProvider({ host, chatLabels, loadExtensionModule, children: app
109
110
  }) : children;
110
111
  return /* @__PURE__ */ jsx(AppHostContext.Provider, {
111
112
  value: host,
112
- children: host.chat ? /* @__PURE__ */ jsx(ChatProvider, {
113
+ children: /* @__PURE__ */ jsx(NoticeStackProvider, { children: host.chat ? /* @__PURE__ */ jsx(ChatProvider, {
113
114
  host: host.chat,
114
115
  ...chatLabels ? { labels: chatLabels } : {},
115
116
  children: withPalette
116
- }) : withPalette
117
+ }) : withPalette })
117
118
  });
118
119
  }
119
120
  /** Returns the {@link AppHost} from the nearest {@link AppHostProvider}. Throws when called outside one. */
@@ -151,20 +151,30 @@ interface ScreenShellProps {
151
151
  headerActions?: ReactNode;
152
152
  /** The main column's body. */
153
153
  children: ReactNode;
154
+ /**
155
+ * On a window too narrow for two columns (a phone), the one pane shown: the left column (`aside`) or the main one
156
+ * (`main`, with a back button to the left column). Absent: the columns sit side by side at any width.
157
+ */
158
+ narrowPane?: 'aside' | 'main';
159
+ /** Back from the main pane to the left column, on a narrow window. */
160
+ onNarrowBack?: () => void;
154
161
  /** Extra classes on the root. */
155
162
  className?: string;
156
163
  /** Inline styles on the root. */
157
164
  style?: CSSProperties;
158
165
  }
166
+ /** Below this window width (px), a {@link ScreenShell} given `narrowPane` shows one pane at a time. */
167
+ declare const SCREEN_NARROW_MAX = 640;
159
168
  /**
160
169
  * Two-column full-window shell mirroring the chat layout: a sidebar-width
161
170
  * left column on the tray tone (traffic-light spacer, back button,
162
171
  * then whatever navigation the surface provides) and a main column with a
163
172
  * heading row over the content. Escape and the back button both call
164
- * `onClose`.
173
+ * `onClose`. On a narrow window with `narrowPane`, one pane at a time at full
174
+ * width: the left column, or the main one under a back button.
165
175
  *
166
176
  * @param props - The heading, the left column, the body and `onClose`.
167
177
  */
168
- declare function ScreenShell({ title, description, lead, screenLabel, onClose, aside, asideFooter, headerActions, children, className, style }: ScreenShellProps): import("react").JSX.Element;
178
+ declare function ScreenShell({ title, description, lead, screenLabel, onClose, aside, asideFooter, headerActions, children, narrowPane, onNarrowBack, className, style }: ScreenShellProps): import("react").JSX.Element;
169
179
  //#endregion
170
- export { LayerOptions, MODAL_TITLE_ID, ModalChromeInset, ModalContextValue, ModalOpenOptions, ModalProvider, ModalProviderProps, ModalScrimKind, ModalShell, ModalShellProps, ModalVariant, ScreenShell, ScreenShellProps, useModal, useOptionalModal };
180
+ export { LayerOptions, MODAL_TITLE_ID, ModalChromeInset, ModalContextValue, ModalOpenOptions, ModalProvider, ModalProviderProps, ModalScrimKind, ModalShell, ModalShellProps, ModalVariant, SCREEN_NARROW_MAX, ScreenShell, ScreenShellProps, useModal, useOptionalModal };