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,6 +1,6 @@
1
1
  import { BTN_SECONDARY } from "../components/button.js";
2
+ import { Notice } from "../components/Notice.js";
2
3
  import { MetaChip } from "../components/Form.js";
3
- import { Restricted } from "../components/Restricted.js";
4
4
  import { machinesError } from "./headless/host.js";
5
5
  import { useMachinesConfirm, useMachinesHost, useMachinesLabels, usePermitted } from "./MachinesProvider.js";
6
6
  import { UPDATE_BUSY_STATES, updateStateLine } from "./headless/messages.js";
@@ -43,9 +43,9 @@ function UpdateBody({ host, updates, confirm, className = "", style }) {
43
43
  setStatus(await action());
44
44
  setError(null);
45
45
  } catch (err) {
46
- setError(labels.machinesError(machinesError("update", err)));
46
+ setError(machinesError("update", err));
47
47
  }
48
- }, [labels]);
48
+ }, []);
49
49
  const readStatus = useCallback(() => run(() => updates.status(host.id)), [
50
50
  run,
51
51
  updates,
@@ -59,10 +59,12 @@ function UpdateBody({ host, updates, confirm, className = "", style }) {
59
59
  const timer = setInterval(() => void readStatus(), POLL_MS);
60
60
  return () => clearInterval(timer);
61
61
  }, [status, readStatus]);
62
- if (status === void 0) return error ? /* @__PURE__ */ jsx("p", {
63
- className: `m-0 px-3 py-3 text-xs text-zg-danger ${className}`.trimEnd(),
62
+ if (status === void 0) return error ? /* @__PURE__ */ jsx(Notice, {
63
+ tone: "error",
64
+ detail: error.detail,
65
+ className: `m-3 ${className}`.trimEnd(),
64
66
  style,
65
- children: error
67
+ children: labels.machinesFailed(error.kind)
66
68
  }) : null;
67
69
  if (status === null) return /* @__PURE__ */ jsx("p", {
68
70
  className: `m-0 px-3 py-3 text-xs text-[var(--zg-text-muted)] ${className}`.trimEnd(),
@@ -71,7 +73,6 @@ function UpdateBody({ host, updates, confirm, className = "", style }) {
71
73
  });
72
74
  const line = updateStateLine(status, labels);
73
75
  const { check, install, configure } = updates;
74
- const restricted = host.scope !== void 0 && host.scope !== "admin";
75
76
  const installNow = async () => {
76
77
  if (!install) return;
77
78
  if (await ask({
@@ -98,43 +99,53 @@ function UpdateBody({ host, updates, confirm, className = "", style }) {
98
99
  /* @__PURE__ */ jsx(MetaChip, { children: labels.machinesUpdateVersion(status.current) }),
99
100
  status.updatedFrom && /* @__PURE__ */ jsx(MetaChip, { children: labels.machinesUpdateFrom(status.updatedFrom) })
100
101
  ]
101
- }), status.supported && (manage || restricted) && /* @__PURE__ */ jsx(Restricted, {
102
- restricted,
103
- reason: labels.machinesAdminOnly,
104
- inline: true,
105
- children: /* @__PURE__ */ jsxs("span", {
106
- className: "flex items-center gap-2",
107
- children: [
108
- check && /* @__PURE__ */ jsx("button", {
109
- type: "button",
110
- className: BTN_SECONDARY,
111
- disabled: UPDATE_BUSY_STATES.has(status.state),
112
- onClick: () => void run(() => check(host.id)),
113
- children: status.state === "checking" ? labels.machinesUpdateChecking : labels.machinesUpdateCheck
114
- }),
115
- (status.state === "ready" || status.state === "waiting") && install && /* @__PURE__ */ jsx("button", {
116
- type: "button",
117
- className: BTN_SECONDARY,
118
- onClick: () => void installNow(),
119
- children: labels.machinesUpdateInstall
120
- }),
121
- configure && /* @__PURE__ */ jsx("button", {
122
- type: "button",
123
- className: BTN_SECONDARY,
124
- onClick: () => void run(() => configure(host.id, !status.enabled)),
125
- children: status.enabled ? labels.machinesUpdateTurnOff : labels.machinesUpdateTurnOn
126
- })
127
- ]
128
- })
102
+ }), status.supported && manage && /* @__PURE__ */ jsxs("span", {
103
+ className: "flex items-center gap-2",
104
+ children: [
105
+ check && /* @__PURE__ */ jsx("button", {
106
+ type: "button",
107
+ className: BTN_SECONDARY,
108
+ disabled: UPDATE_BUSY_STATES.has(status.state),
109
+ onClick: () => void run(() => check(host.id)),
110
+ children: status.state === "checking" ? labels.machinesUpdateChecking : labels.machinesUpdateCheck
111
+ }),
112
+ (status.state === "ready" || status.state === "waiting") && install && /* @__PURE__ */ jsx("button", {
113
+ type: "button",
114
+ className: BTN_SECONDARY,
115
+ onClick: () => void installNow(),
116
+ children: labels.machinesUpdateInstall
117
+ }),
118
+ configure && /* @__PURE__ */ jsx("button", {
119
+ type: "button",
120
+ className: BTN_SECONDARY,
121
+ onClick: () => void run(() => configure(host.id, !status.enabled)),
122
+ children: status.enabled ? labels.machinesUpdateTurnOff : labels.machinesUpdateTurnOn
123
+ })
124
+ ]
129
125
  })]
130
126
  }),
131
- /* @__PURE__ */ jsx("p", {
132
- className: `m-0 text-xs ${line.tone === "danger" ? "text-zg-danger" : line.tone === "warn" ? "text-zg-warn" : line.tone === "success" ? "text-zg-success" : "text-[var(--zg-text-muted)]"}`,
127
+ status.state === "error" && status.error ? /* @__PURE__ */ jsx(Notice, {
128
+ tone: "error",
129
+ compact: true,
130
+ detail: status.error,
131
+ children: labels.machinesUpdateStateError
132
+ }) : line.tone === "danger" ? /* @__PURE__ */ jsx(Notice, {
133
+ tone: "error",
134
+ compact: true,
135
+ children: line.text
136
+ }) : line.tone === "warn" ? /* @__PURE__ */ jsx(Notice, {
137
+ tone: "warning",
138
+ compact: true,
139
+ children: line.text
140
+ }) : /* @__PURE__ */ jsx("p", {
141
+ className: `m-0 text-xs ${line.tone === "success" ? "text-zg-success" : "text-[var(--zg-text-muted)]"}`,
133
142
  children: line.text
134
143
  }),
135
- error && /* @__PURE__ */ jsx("p", {
136
- className: "m-0 text-xs text-zg-danger",
137
- children: error
144
+ error && /* @__PURE__ */ jsx(Notice, {
145
+ tone: "error",
146
+ compact: true,
147
+ detail: error.detail,
148
+ children: labels.machinesFailed(error.kind)
138
149
  })
139
150
  ]
140
151
  });
@@ -0,0 +1,19 @@
1
+ import { HostSummary } from "./headless/host.js";
2
+ //#region src/machines/ShareThisComputerForm.d.ts
3
+ /** Props for {@link ShareThisComputerForm}. */
4
+ interface ShareThisComputerFormProps {
5
+ /** The server to share with. */
6
+ host: HostSummary;
7
+ /** Called once this computer is shared. */
8
+ onShared: () => void;
9
+ /** Called on Cancel. Absent: no Cancel button. */
10
+ onCancel?: () => void;
11
+ }
12
+ /**
13
+ * Renders the form that shares this computer with a server. Nothing without the host's `links.shareStart`.
14
+ *
15
+ * @param props - The server, and what to do once shared or cancelled.
16
+ */
17
+ declare function ShareThisComputerForm({ host, onShared, onCancel }: ShareThisComputerFormProps): import("react").JSX.Element | null;
18
+ //#endregion
19
+ export { ShareThisComputerForm, ShareThisComputerFormProps };
@@ -0,0 +1,133 @@
1
+ import { BTN_PRIMARY, BTN_SECONDARY } from "../components/button.js";
2
+ import { FIELD_LABEL_CLASS, INPUT_CLASS, OpLine } from "../components/Form.js";
3
+ import { machinesError } from "./headless/host.js";
4
+ import { useMachinesHost, useMachinesLabels } from "./MachinesProvider.js";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { useState } from "react";
7
+ //#region src/machines/ShareThisComputerForm.tsx
8
+ /**
9
+ * Shares this computer with a server as one of its machines (the host's
10
+ * `links.shareStart`): a name (default: this computer's), the folders that
11
+ * the server can use (the host's folder dialog), and a machine token when
12
+ * the server does not make one. Add a machine's This computer tab shows it.
13
+ */
14
+ /**
15
+ * Renders the form that shares this computer with a server. Nothing without the host's `links.shareStart`.
16
+ *
17
+ * @param props - The server, and what to do once shared or cancelled.
18
+ */
19
+ function ShareThisComputerForm({ host, onShared, onCancel }) {
20
+ const labels = useMachinesLabels();
21
+ const { links, pickFolder } = useMachinesHost();
22
+ const [name, setName] = useState("");
23
+ const [roots, setRoots] = useState([]);
24
+ const [token, setToken] = useState("");
25
+ const [needsToken, setNeedsToken] = useState(false);
26
+ const [busy, setBusy] = useState(false);
27
+ const [error, setError] = useState(null);
28
+ const shareStart = links?.shareStart;
29
+ if (!shareStart) return null;
30
+ const addFolder = async () => {
31
+ const path = await pickFolder?.();
32
+ if (path) setRoots((current) => current.includes(path) ? current : [...current, path]);
33
+ };
34
+ const submit = async () => {
35
+ setBusy(true);
36
+ setError(null);
37
+ try {
38
+ const result = await shareStart(host.id, name.trim(), roots, token.trim() || void 0);
39
+ if (result.ok) {
40
+ links.refresh();
41
+ onShared();
42
+ return;
43
+ }
44
+ if (result.needsToken) setNeedsToken(true);
45
+ setError(result.message);
46
+ } catch (err) {
47
+ setError(labels.machinesError(machinesError("read", err)));
48
+ } finally {
49
+ setBusy(false);
50
+ }
51
+ };
52
+ return /* @__PURE__ */ jsxs("form", {
53
+ className: "space-y-2",
54
+ "aria-label": labels.machinesShareForm,
55
+ onSubmit: (event) => {
56
+ event.preventDefault();
57
+ submit();
58
+ },
59
+ children: [
60
+ /* @__PURE__ */ jsx("label", {
61
+ className: FIELD_LABEL_CLASS,
62
+ htmlFor: `machine-name-${host.id}`,
63
+ children: labels.machinesShareName(host.name)
64
+ }),
65
+ /* @__PURE__ */ jsx("input", {
66
+ id: `machine-name-${host.id}`,
67
+ className: INPUT_CLASS,
68
+ placeholder: labels.machinesShareNamePlaceholder,
69
+ value: name,
70
+ maxLength: 64,
71
+ onChange: (event) => setName(event.target.value)
72
+ }),
73
+ /* @__PURE__ */ jsx("div", {
74
+ className: FIELD_LABEL_CLASS,
75
+ children: labels.machinesShareFolders
76
+ }),
77
+ roots.length > 0 && /* @__PURE__ */ jsx("ul", {
78
+ className: "m-0 p-0 list-none space-y-1",
79
+ children: roots.map((root) => /* @__PURE__ */ jsxs("li", {
80
+ className: "flex items-center gap-2 text-xs",
81
+ children: [/* @__PURE__ */ jsx("span", {
82
+ className: "flex-1 truncate font-mono",
83
+ children: root
84
+ }), /* @__PURE__ */ jsx("button", {
85
+ type: "button",
86
+ className: BTN_SECONDARY,
87
+ onClick: () => setRoots((current) => current.filter((r) => r !== root)),
88
+ children: labels.machinesRemove
89
+ })]
90
+ }, root))
91
+ }),
92
+ pickFolder && /* @__PURE__ */ jsx("button", {
93
+ type: "button",
94
+ className: BTN_SECONDARY,
95
+ onClick: () => void addFolder(),
96
+ children: labels.machinesShareAddFolder
97
+ }),
98
+ needsToken && /* @__PURE__ */ jsx("input", {
99
+ "aria-label": labels.machinesShareToken,
100
+ type: "password",
101
+ autoComplete: "off",
102
+ className: "zg-well w-full h-8 px-2.5 text-zg-ui placeholder:text-[var(--zg-text-subtle)] disabled:opacity-zg-disabled",
103
+ placeholder: labels.machinesShareTokenPlaceholder,
104
+ value: token,
105
+ onChange: (event) => setToken(event.target.value)
106
+ }),
107
+ busy && /* @__PURE__ */ jsx(OpLine, {
108
+ kind: "busy",
109
+ children: labels.machinesSharing(host.name)
110
+ }),
111
+ error && !busy && /* @__PURE__ */ jsx(OpLine, {
112
+ kind: "error",
113
+ children: error
114
+ }),
115
+ /* @__PURE__ */ jsxs("div", {
116
+ className: "flex justify-end gap-2",
117
+ children: [onCancel && /* @__PURE__ */ jsx("button", {
118
+ type: "button",
119
+ className: BTN_SECONDARY,
120
+ onClick: onCancel,
121
+ children: labels.machinesCancel
122
+ }), /* @__PURE__ */ jsx("button", {
123
+ type: "submit",
124
+ className: BTN_PRIMARY,
125
+ disabled: busy || roots.length === 0,
126
+ children: labels.machinesShareStart
127
+ })]
128
+ })
129
+ ]
130
+ });
131
+ }
132
+ //#endregion
133
+ export { ShareThisComputerForm };
@@ -1,7 +1,7 @@
1
1
  import { Tooltip } from "../components/Tooltip.js";
2
2
  import { MetaChip } from "../components/Form.js";
3
- import { syncOutcome } from "./headless/sync.js";
4
3
  import { useMachinesLabels } from "./MachinesProvider.js";
4
+ import { syncOutcome } from "./headless/sync.js";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
6
  //#region src/machines/SyncOutcomeBadge.tsx
7
7
  const MAX_LINES = 12;
@@ -10,16 +10,18 @@ interface TokensPanelProps {
10
10
  confirm?: MachinesConfirm;
11
11
  /** The current time for the dates, epoch ms. Default: now. */
12
12
  now?: number;
13
+ /** Where the web app is, said next to a pairing code. Default: the server's URL as https. */
14
+ webAppUrl?: string;
13
15
  /** Extra classes on the root. */
14
16
  className?: string;
15
17
  /** Inline styles on the root. */
16
18
  style?: CSSProperties;
17
19
  }
18
20
  /**
19
- * Renders a server's tokens and the create form. Nothing without the host's `tokens`, or while the connection's
20
- * permissions are not known.
21
+ * Renders a server's tokens, the create form and Pair a browser. Nothing without the host's `tokens`, or when the
22
+ * server does not list them.
21
23
  *
22
- * @param props - The server, `confirm`, `className` and `style`.
24
+ * @param props - The server, `confirm`, `now`, `webAppUrl`, `className` and `style`.
23
25
  */
24
26
  declare function TokensPanel(props: TokensPanelProps): import("react").JSX.Element | null;
25
27
  //#endregion
@@ -1,59 +1,44 @@
1
- import { BTN_DANGER, BTN_PRIMARY } from "../components/button.js";
1
+ import { BTN_DANGER, BTN_PRIMARY, BTN_SECONDARY } from "../components/button.js";
2
2
  import { CopyButton } from "../components/CopyButton.js";
3
3
  import { ErrorNote, FIELD_LABEL_CLASS, INPUT_CLASS, MetaChip, OpLine } from "../components/Form.js";
4
- import { Restricted } from "../components/Restricted.js";
5
4
  import { machinesError } from "./headless/host.js";
6
5
  import { useMachinesConfirm, useMachinesHost, useMachinesLabels, usePermitted } from "./MachinesProvider.js";
7
6
  import { agoText } from "./headless/messages.js";
8
7
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
8
  import { useCallback, useEffect, useState } from "react";
9
+ import { clockText } from "zidane/chat/pure";
10
10
  //#region src/machines/TokensPanel.tsx
11
11
  /**
12
- * A server's client tokens: each with its scope, when it was created and last
13
- * used, when it expires, and Revoke (asks first); a form that creates one and shows its secret
14
- * once. Needs the host's `tokens`; a token that may not manage them (below
15
- * admin) reads a note instead.
12
+ * A server's tokens: each with its kind (client or machine), when it was
13
+ * created and last used, when it expires, and Revoke (asks first). A form
14
+ * creates a client token and shows its secret once. Pair a browser makes a
15
+ * pairing code for the web app's sign-in screen. Needs the host's `tokens`.
16
16
  */
17
17
  /** Whether a token's `expiresAt` is past at `now` (default the current time). */
18
18
  function isExpired(expiresAt, now = Date.now()) {
19
19
  return expiresAt <= now;
20
20
  }
21
- const SCOPES = ["chat", "admin"];
22
21
  /**
23
- * Renders a server's tokens and the create form. Nothing without the host's `tokens`, or while the connection's
24
- * permissions are not known.
22
+ * Renders a server's tokens, the create form and Pair a browser. Nothing without the host's `tokens`, or when the
23
+ * server does not list them.
25
24
  *
26
- * @param props - The server, `confirm`, `className` and `style`.
25
+ * @param props - The server, `confirm`, `now`, `webAppUrl`, `className` and `style`.
27
26
  */
28
27
  function TokensPanel(props) {
29
- const labels = useMachinesLabels();
30
28
  const host = useMachinesHost();
31
29
  const readable = usePermitted("tokens.list");
32
- const permittedKnown = host.permitted === void 0 || host.permitted.get() !== null;
33
- if (!host.tokens) return null;
34
- if (!readable) return permittedKnown ? /* @__PURE__ */ jsx(Restricted, {
35
- restricted: true,
36
- reason: labels.machinesAdminOnly,
37
- children: /* @__PURE__ */ jsx("div", {
38
- className: `px-3 py-3 ${props.className ?? ""}`.trimEnd(),
39
- style: props.style,
40
- children: /* @__PURE__ */ jsx(TokenForm, {
41
- fieldId: `tokens-${props.host.id}`,
42
- name: "",
43
- scope: "chat",
44
- busy: false,
45
- onName: () => {},
46
- onScope: () => {},
47
- onSubmit: () => {}
48
- })
49
- })
50
- }) : null;
30
+ if (!host.tokens || !readable) return null;
51
31
  return /* @__PURE__ */ jsx(TokensBody, {
52
32
  ...props,
53
33
  tokens: host.tokens
54
34
  });
55
35
  }
56
- function TokensBody({ host, tokens, confirm, now, className = "", style }) {
36
+ /** The web app's address for a server's WebSocket URL: `wss://box` → `https://box`. */
37
+ function webAppOf(url) {
38
+ if (!url) return void 0;
39
+ return url.replace(/^ws(s?):/i, "http$1:").replace(/\/+$/, "");
40
+ }
41
+ function TokensBody({ host, tokens, confirm, now, webAppUrl, className = "", style }) {
57
42
  const labels = useMachinesLabels();
58
43
  const providerConfirm = useMachinesConfirm();
59
44
  const ask = confirm ?? providerConfirm;
@@ -62,9 +47,10 @@ function TokensBody({ host, tokens, confirm, now, className = "", style }) {
62
47
  const [readError, setReadError] = useState(null);
63
48
  const [error, setError] = useState(null);
64
49
  const [name, setName] = useState("");
65
- const [scope, setScope] = useState("chat");
66
50
  const [busy, setBusy] = useState(false);
67
51
  const [created, setCreated] = useState(null);
52
+ const [pairing, setPairing] = useState(null);
53
+ const [pairBusy, setPairBusy] = useState(false);
68
54
  const fieldId = `tokens-${host.id}`;
69
55
  const read = useCallback(async () => {
70
56
  try {
@@ -86,13 +72,13 @@ function TokensBody({ host, tokens, confirm, now, className = "", style }) {
86
72
  tokens,
87
73
  host.id
88
74
  ]);
89
- const { create, revoke } = tokens;
75
+ const { create, revoke, pair } = tokens;
90
76
  const submit = async () => {
91
77
  if (!create || !name.trim()) return;
92
78
  setBusy(true);
93
79
  setCreated(null);
94
80
  try {
95
- setCreated(await create(host.id, name.trim(), scope));
81
+ setCreated(await create(host.id, name.trim()));
96
82
  setName("");
97
83
  setError(null);
98
84
  } catch (err) {
@@ -102,6 +88,20 @@ function TokensBody({ host, tokens, confirm, now, className = "", style }) {
102
88
  read();
103
89
  }
104
90
  };
91
+ const pairBrowser = async () => {
92
+ if (!pair) return;
93
+ setPairBusy(true);
94
+ setPairing(null);
95
+ try {
96
+ setPairing(await pair(host.id));
97
+ setError(null);
98
+ } catch (err) {
99
+ setError(labels.machinesError(machinesError("tokens", err)));
100
+ } finally {
101
+ setPairBusy(false);
102
+ read();
103
+ }
104
+ };
105
105
  const revokeOne = async (token) => {
106
106
  if (!revoke) return;
107
107
  if (!await ask({
@@ -139,10 +139,7 @@ function TokensBody({ host, tokens, confirm, now, className = "", style }) {
139
139
  className: `font-medium ${token.revokedAt || expired ? "text-[var(--zg-text-muted)] line-through" : "text-[var(--zg-text)]"}`,
140
140
  children: token.name
141
141
  }),
142
- /* @__PURE__ */ jsx(MetaChip, {
143
- tone: token.scope === "admin" ? "warn" : "muted",
144
- children: labels.machinesTokensScopes[token.scope]
145
- }),
142
+ /* @__PURE__ */ jsx(MetaChip, { children: labels.machinesTokensScopes[token.scope] ?? token.scope }),
146
143
  token.revokedAt && /* @__PURE__ */ jsx(MetaChip, {
147
144
  tone: "danger",
148
145
  children: labels.machinesTokensRevoked
@@ -152,7 +149,7 @@ function TokensBody({ host, tokens, confirm, now, className = "", style }) {
152
149
  children: labels.machinesTokensExpired
153
150
  }),
154
151
  /* @__PURE__ */ jsxs("span", {
155
- className: "flex-1 min-w-0 truncate text-[var(--zg-text-muted)]",
152
+ className: "flex-1 min-w-[12rem] truncate text-[var(--zg-text-muted)]",
156
153
  children: [
157
154
  token.lastUsedAt ? labels.machinesTokensUsed(agoText(token.lastUsedAt, now, labels)) : labels.machinesTokensNeverUsed,
158
155
  " · ",
@@ -174,12 +171,52 @@ function TokensBody({ host, tokens, confirm, now, className = "", style }) {
174
171
  create && manage && /* @__PURE__ */ jsx(TokenForm, {
175
172
  fieldId,
176
173
  name,
177
- scope,
178
174
  busy,
179
175
  onName: setName,
180
- onScope: setScope,
181
176
  onSubmit: () => void submit()
182
177
  }),
178
+ pair && manage && !pairing && /* @__PURE__ */ jsx("button", {
179
+ type: "button",
180
+ className: BTN_SECONDARY,
181
+ disabled: pairBusy,
182
+ onClick: () => void pairBrowser(),
183
+ children: pairBusy ? labels.machinesPairCreating : labels.machinesPairOpen
184
+ }),
185
+ pairing && /* @__PURE__ */ jsxs("div", {
186
+ className: "space-y-1.5",
187
+ role: "status",
188
+ "data-testid": `pairing-${host.id}`,
189
+ children: [
190
+ /* @__PURE__ */ jsx("span", {
191
+ className: "block text-xs text-[var(--zg-text-muted)] mb-1",
192
+ children: labels.machinesPairCode
193
+ }),
194
+ /* @__PURE__ */ jsxs("div", {
195
+ className: "zg-well flex items-center gap-2 rounded-zg-md px-2.5 py-1.5",
196
+ children: [/* @__PURE__ */ jsx("code", {
197
+ className: "flex-1 min-w-0 font-mono text-sm tracking-[0.2em] text-[var(--zg-text)]",
198
+ children: pairing.code
199
+ }), /* @__PURE__ */ jsx(CopyButton, {
200
+ text: pairing.code,
201
+ label: labels.machinesPairCopy
202
+ })]
203
+ }),
204
+ /* @__PURE__ */ jsxs("p", {
205
+ className: "m-0 text-xs text-[var(--zg-text-muted)]",
206
+ children: [
207
+ labels.machinesPairHint(webAppUrl ?? webAppOf(host.url)),
208
+ " ",
209
+ labels.machinesPairExpires(clockText(pairing.expiresAt))
210
+ ]
211
+ }),
212
+ /* @__PURE__ */ jsx("button", {
213
+ type: "button",
214
+ className: BTN_SECONDARY,
215
+ onClick: () => setPairing(null),
216
+ children: labels.machinesPairDone
217
+ })
218
+ ]
219
+ }),
183
220
  created && /* @__PURE__ */ jsxs("div", {
184
221
  className: "space-y-1",
185
222
  role: "status",
@@ -201,8 +238,8 @@ function TokensBody({ host, tokens, confirm, now, className = "", style }) {
201
238
  ]
202
239
  });
203
240
  }
204
- /** The create form: a name and a scope. */
205
- function TokenForm({ fieldId, name, scope, busy, onName, onScope, onSubmit }) {
241
+ /** The create form: a name. */
242
+ function TokenForm({ fieldId, name, busy, onName, onSubmit }) {
206
243
  const labels = useMachinesLabels();
207
244
  return /* @__PURE__ */ jsxs("form", {
208
245
  className: "flex flex-wrap items-end gap-2",
@@ -210,43 +247,26 @@ function TokenForm({ fieldId, name, scope, busy, onName, onScope, onSubmit }) {
210
247
  event.preventDefault();
211
248
  onSubmit();
212
249
  },
213
- children: [
214
- /* @__PURE__ */ jsxs("div", {
215
- className: "flex-1 min-w-40",
216
- children: [/* @__PURE__ */ jsx("label", {
217
- className: FIELD_LABEL_CLASS,
218
- htmlFor: `${fieldId}-name`,
219
- children: labels.machinesTokensName
220
- }), /* @__PURE__ */ jsx("input", {
221
- id: `${fieldId}-name`,
222
- className: INPUT_CLASS,
223
- placeholder: labels.machinesTokensNamePlaceholder,
224
- value: name,
225
- maxLength: 200,
226
- onChange: (event) => onName(event.target.value)
227
- })]
228
- }),
229
- /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("label", {
250
+ children: [/* @__PURE__ */ jsxs("div", {
251
+ className: "flex-1 min-w-40",
252
+ children: [/* @__PURE__ */ jsx("label", {
230
253
  className: FIELD_LABEL_CLASS,
231
- htmlFor: `${fieldId}-scope`,
232
- children: labels.machinesTokensScope
233
- }), /* @__PURE__ */ jsx("select", {
234
- id: `${fieldId}-scope`,
254
+ htmlFor: `${fieldId}-name`,
255
+ children: labels.machinesTokensName
256
+ }), /* @__PURE__ */ jsx("input", {
257
+ id: `${fieldId}-name`,
235
258
  className: INPUT_CLASS,
236
- value: scope,
237
- onChange: (event) => onScope(event.target.value),
238
- children: SCOPES.map((option) => /* @__PURE__ */ jsx("option", {
239
- value: option,
240
- children: labels.machinesTokensScopes[option]
241
- }, option))
242
- })] }),
243
- /* @__PURE__ */ jsx("button", {
244
- type: "submit",
245
- className: BTN_PRIMARY,
246
- disabled: busy || !name.trim(),
247
- children: busy ? labels.machinesTokensCreating : labels.machinesTokensCreate
248
- })
249
- ]
259
+ placeholder: labels.machinesTokensNamePlaceholder,
260
+ value: name,
261
+ maxLength: 200,
262
+ onChange: (event) => onName(event.target.value)
263
+ })]
264
+ }), /* @__PURE__ */ jsx("button", {
265
+ type: "submit",
266
+ className: BTN_PRIMARY,
267
+ disabled: busy || !name.trim(),
268
+ children: busy ? labels.machinesTokensCreating : labels.machinesTokensCreate
269
+ })]
250
270
  });
251
271
  }
252
272
  //#endregion
@@ -1,7 +1,7 @@
1
1
  import { SessionPresence } from "./presence.js";
2
2
  import { HostSyncState } from "./sync.js";
3
- import { DaemonStatus, HostProviderAuth, HostSummary, MachinesAction, MachinesHost, ServerToken, ServerTokenScope } from "./host.js";
4
- import { DaemonHealth, HostCapabilities, MachineInfo, MachineLinksStatus, ServerUpdateStatus } from "zidane/chat/pure";
3
+ import { DaemonStatus, HostProviderAuth, HostSummary, MachinesAction, MachinesHost, ServerToken } from "./host.js";
4
+ import { DaemonHealth, HostCapabilities, MachineInfo, MachineJoinEvent, MachineLinksStatus, ServerUpdateStatus } from "zidane/chat/pure";
5
5
  //#region src/machines/headless/fixture-host.d.ts
6
6
  /** Options of {@link createFixtureMachinesHost}. */
7
7
  interface FixtureMachinesOptions {
@@ -70,7 +70,12 @@ interface FixtureMachinesOptions {
70
70
  /** Called when an update action reaches the fixture. */
71
71
  onUpdate?: (hostId: string, action: 'check' | 'install' | 'configure', enabled?: boolean) => void;
72
72
  /** Called when a token is created. */
73
- onCreateToken?: (hostId: string, name: string, scope: ServerTokenScope) => void;
73
+ onCreateToken?: (hostId: string, name: string) => void;
74
+ /** Called when a browser pairing code is asked for. */
75
+ onPair?: (hostId: string, options: {
76
+ name?: string;
77
+ ttlMs?: number;
78
+ }) => void;
74
79
  /** Called when a token is revoked. */
75
80
  onRevokeToken?: (hostId: string, id: string) => void;
76
81
  /** Called when a link action reaches the fixture. */
@@ -91,6 +96,13 @@ interface FixtureMachinesOptions {
91
96
  signInUrl?: string;
92
97
  /** Called when a sign-in starts. */
93
98
  onSignIn?: (hostId: string, target: unknown) => void;
99
+ /** Called when New chat is pressed (the host's `newChat`). */
100
+ onNewChat?: (hostId: string, machine?: string) => void;
101
+ /**
102
+ * A machine that joins this long after each join code is made, ms (the docs' live demo of Add a machine).
103
+ * Default: none joins by itself (`control.joinMachine`).
104
+ */
105
+ joinAfterMs?: number;
94
106
  }
95
107
  /** Pushes the fixture can make, as a backend would. */
96
108
  interface FixtureMachinesControl {
@@ -98,6 +110,10 @@ interface FixtureMachinesControl {
98
110
  setHosts(hosts: readonly HostSummary[]): void;
99
111
  /** A machine came online or went offline: its server's list follows. */
100
112
  setMachineStatus(hostId: string, machineId: string, status: 'online' | 'offline'): void;
113
+ /** A new machine joined a server (it registered, online): its list follows. */
114
+ joinMachine(hostId: string, machine: MachineInfo): void;
115
+ /** What became of a join code, as the server says it (`machine:join`). */
116
+ pushJoin(hostId: string, event: MachineJoinEvent): void;
101
117
  /** Replaces the links (a links push). */
102
118
  setLinks(links: MachineLinksStatus): void;
103
119
  /** Sets the daemon's health. */