zidane-ui 9.1.13 → 9.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (290) hide show
  1. package/dist/adapters/index.d.ts +2 -2
  2. package/dist/adapters/index.js +2 -2
  3. package/dist/adapters/live.d.ts +29 -3
  4. package/dist/adapters/live.js +9 -1
  5. package/dist/adapters/server-composer-host.js +17 -2
  6. package/dist/adapters/server-extensions-host.d.ts +0 -1
  7. package/dist/adapters/server-extensions-host.js +4 -15
  8. package/dist/adapters/server-git-host.js +7 -16
  9. package/dist/adapters/server-host.js +181 -43
  10. package/dist/adapters/server-machines-host.d.ts +2 -0
  11. package/dist/adapters/server-machines-host.js +22 -23
  12. package/dist/adapters/server-onboarding-host.d.ts +1 -1
  13. package/dist/adapters/server-onboarding-host.js +3 -4
  14. package/dist/adapters/server-session-host.js +22 -3
  15. package/dist/adapters/server-settings-accounts.js +2 -2
  16. package/dist/adapters/server-settings-host.js +2 -2
  17. package/dist/adapters/server-settings-performance.js +7 -9
  18. package/dist/adapters/server-settings-sections.js +13 -14
  19. package/dist/adapters/server-sidebar-host.js +2 -2
  20. package/dist/adapters/sse-host.js +68 -3
  21. package/dist/adapters/sse-protocol.d.ts +12 -2
  22. package/dist/adapters/sse-protocol.js +4 -2
  23. package/dist/app/AppHostProvider.js +4 -3
  24. package/dist/app/ModalProvider.d.ts +13 -3
  25. package/dist/app/ModalProvider.js +103 -24
  26. package/dist/app/NoticeStack.d.ts +33 -0
  27. package/dist/app/NoticeStack.js +90 -0
  28. package/dist/app/index.d.ts +3 -2
  29. package/dist/app/index.js +3 -2
  30. package/dist/chat/SessionFilterMenu.d.ts +1 -1
  31. package/dist/chat/SessionFilterMenu.js +2 -1
  32. package/dist/chat/composer/Composer.js +10 -8
  33. package/dist/chat/composer/ModelChainList.js +17 -8
  34. package/dist/chat/composer/ModelChainTooltip.js +5 -2
  35. package/dist/chat/composer/use-draft-target.d.ts +20 -1
  36. package/dist/chat/composer/use-draft-target.js +121 -5
  37. package/dist/chat/composer/use-new-session-defaults.d.ts +5 -1
  38. package/dist/chat/composer/use-new-session-defaults.js +17 -4
  39. package/dist/chat/headless/chip-labels.d.ts +1 -0
  40. package/dist/chat/headless/chip-labels.js +1 -0
  41. package/dist/chat/headless/composer/labels-editor.d.ts +0 -2
  42. package/dist/chat/headless/composer/labels-editor.js +0 -2
  43. package/dist/chat/headless/draft-target.d.ts +21 -1
  44. package/dist/chat/headless/fixture-host.js +17 -2
  45. package/dist/chat/headless/host.d.ts +3 -3
  46. package/dist/chat/headless/index.d.ts +9 -9
  47. package/dist/chat/headless/index.js +2 -2
  48. package/dist/chat/headless/labels.d.ts +13 -6
  49. package/dist/chat/headless/labels.js +10 -9
  50. package/dist/chat/headless/session-list.d.ts +20 -8
  51. package/dist/chat/headless/session-list.js +1 -0
  52. package/dist/chat/headless/sidebar/directory.d.ts +56 -14
  53. package/dist/chat/headless/sidebar/directory.js +149 -70
  54. package/dist/chat/headless/sidebar/index.d.ts +3 -3
  55. package/dist/chat/headless/sidebar/index.js +2 -2
  56. package/dist/chat/headless/sidebar/labels.d.ts +15 -8
  57. package/dist/chat/headless/sidebar/types.d.ts +3 -1
  58. package/dist/chat/headless/sidebar/view.d.ts +13 -5
  59. package/dist/chat/headless/sidebar/view.js +31 -11
  60. package/dist/chat/headless/streams/actions.d.ts +5 -3
  61. package/dist/chat/headless/streams/actions.js +3 -2
  62. package/dist/chat/headless/streams/index.d.ts +3 -3
  63. package/dist/chat/headless/streams/merge.d.ts +6 -10
  64. package/dist/chat/headless/streams/merge.js +7 -21
  65. package/dist/chat/headless/streams/session-streams.d.ts +29 -4
  66. package/dist/chat/headless/streams/session-streams.js +86 -0
  67. package/dist/chat/headless/streams/store.d.ts +162 -16
  68. package/dist/chat/headless/streams/store.js +334 -38
  69. package/dist/chat/headless/streams/types.d.ts +10 -7
  70. package/dist/chat/headless/transcript-labels.d.ts +1 -0
  71. package/dist/chat/interactions/PlanCard.js +10 -3
  72. package/dist/chat/interactions/QuestionForm.js +7 -3
  73. package/dist/chat/interactions/card-ui.d.ts +5 -3
  74. package/dist/chat/interactions/card-ui.js +9 -7
  75. package/dist/chat/rich-composer/RichComposer.js +1 -7
  76. package/dist/chat/rich-composer/composer-extensions.d.ts +0 -2
  77. package/dist/chat/rich-composer/composer-extensions.js +2 -2
  78. package/dist/chat/rich-composer/use-composer-editor.d.ts +0 -2
  79. package/dist/chat/rich-composer/use-composer-editor.js +1 -2
  80. package/dist/chat/sidebar/SessionSidebar.js +5 -5
  81. package/dist/chat/sidebar/SidebarFilterMenu.js +3 -1
  82. package/dist/chat/sidebar/SidebarFrame.d.ts +4 -0
  83. package/dist/chat/sidebar/SidebarFrame.js +27 -9
  84. package/dist/chat/sidebar/SidebarGroupHeader.js +1 -1
  85. package/dist/chat/sidebar/SidebarHostProvider.d.ts +8 -5
  86. package/dist/chat/sidebar/SidebarHostProvider.js +13 -9
  87. package/dist/chat/sidebar/SidebarToggleButton.js +7 -3
  88. package/dist/chat/sidebar/index.d.ts +2 -2
  89. package/dist/chat/sidebar/session-menu.js +4 -4
  90. package/dist/chat/sidebar/useSaveViewAsSpace.js +2 -2
  91. package/dist/chat/testing/contract.js +2 -2
  92. package/dist/chat/transcript/AuthFailureCard.js +11 -8
  93. package/dist/chat/transcript/BadgeMenu.js +13 -2
  94. package/dist/chat/transcript/MermaidDiagram.js +7 -3
  95. package/dist/chat/transcript/fold.d.ts +4 -0
  96. package/dist/chat/transcript/fold.js +53 -22
  97. package/dist/chat/transcript/script-input.d.ts +1 -1
  98. package/dist/chat/transcript/shell-block.js +7 -3
  99. package/dist/chat/transcript/useStickToBottom.js +12 -0
  100. package/dist/components/BrowserSignIn.js +23 -21
  101. package/dist/components/Form.d.ts +6 -4
  102. package/dist/components/Form.js +16 -8
  103. package/dist/components/LoadError.d.ts +4 -2
  104. package/dist/components/LoadError.js +13 -9
  105. package/dist/components/Notice.d.ts +29 -0
  106. package/dist/components/Notice.js +63 -0
  107. package/dist/components/PanelEmpty.d.ts +1 -1
  108. package/dist/components/PanelEmpty.js +4 -2
  109. package/dist/components/Restricted.d.ts +1 -1
  110. package/dist/components/palette/PaletteList.js +8 -1
  111. package/dist/components/palette/PalettePanel.js +14 -6
  112. package/dist/core.css +24 -5
  113. package/dist/dist/{index-Bq87OcGy.d.ts → index-BZM8tu4L.d.ts} +28 -3
  114. package/dist/dist/index.d.ts +2 -2
  115. package/dist/dist/{timeout-B5pO5I5a.d.ts → timeout-Cyx3VGPz.d.ts} +1 -1
  116. package/dist/extensions/ExtensionSettingsPage.js +1 -4
  117. package/dist/extensions/ExtensionSettingsSection.js +4 -3
  118. package/dist/extensions/ExtensionSettingsSidebar.js +2 -6
  119. package/dist/extensions/SettingsWireForm.d.ts +1 -7
  120. package/dist/extensions/SettingsWireForm.js +7 -5
  121. package/dist/extensions/headless/fixture-host.d.ts +1 -5
  122. package/dist/extensions/headless/fixture-host.js +1 -4
  123. package/dist/extensions/headless/host.d.ts +1 -11
  124. package/dist/extensions/headless/index.d.ts +3 -3
  125. package/dist/extensions/headless/index.js +2 -2
  126. package/dist/extensions/headless/select.d.ts +1 -11
  127. package/dist/extensions/headless/select.js +1 -18
  128. package/dist/files/EditorColumn.js +12 -1
  129. package/dist/files/TreeColumn.js +13 -20
  130. package/dist/files/useOpenFiles.js +2 -0
  131. package/dist/git/BranchMenu.js +5 -3
  132. package/dist/git/ImportRepoDialog.js +18 -9
  133. package/dist/git/MoveSessionDialog.js +15 -7
  134. package/dist/git/RemoteFolderPicker.js +34 -16
  135. package/dist/git/SyncChip.js +17 -17
  136. package/dist/git/WherePicker.d.ts +16 -1
  137. package/dist/git/WherePicker.js +80 -36
  138. package/dist/git/headless/environment.d.ts +33 -3
  139. package/dist/git/headless/environment.js +33 -5
  140. package/dist/git/headless/index.d.ts +2 -2
  141. package/dist/git/headless/index.js +2 -2
  142. package/dist/git/headless/labels.d.ts +15 -2
  143. package/dist/git/headless/labels.js +17 -4
  144. package/dist/git/useEnvironmentChoices.d.ts +3 -1
  145. package/dist/git/useEnvironmentChoices.js +6 -3
  146. package/dist/index.d.ts +2 -1
  147. package/dist/index.js +2 -1
  148. package/dist/labels.d.ts +5 -0
  149. package/dist/labels.js +5 -0
  150. package/dist/machines/AddMachineDialog.d.ts +34 -0
  151. package/dist/machines/AddMachineDialog.js +464 -0
  152. package/dist/machines/Banners.d.ts +33 -4
  153. package/dist/machines/Banners.js +64 -3
  154. package/dist/machines/DaemonMenu.js +27 -4
  155. package/dist/machines/HostCapabilities.d.ts +1 -3
  156. package/dist/machines/HostCapabilities.js +24 -45
  157. package/dist/machines/HostSyncPanel.js +123 -129
  158. package/dist/machines/HostsSection.d.ts +4 -1
  159. package/dist/machines/HostsSection.js +30 -7
  160. package/dist/machines/MachinesExplainer.d.ts +17 -0
  161. package/dist/machines/MachinesExplainer.js +71 -0
  162. package/dist/machines/MachinesProvider.d.ts +14 -2
  163. package/dist/machines/MachinesProvider.js +35 -1
  164. package/dist/machines/ServerAddedCard.d.ts +31 -0
  165. package/dist/machines/ServerAddedCard.js +72 -0
  166. package/dist/machines/ServerCard.js +91 -215
  167. package/dist/machines/ServerMachinesPanel.d.ts +2 -2
  168. package/dist/machines/ServerMachinesPanel.js +184 -323
  169. package/dist/machines/ServerUpdatePanel.js +51 -40
  170. package/dist/machines/ShareThisComputerForm.d.ts +19 -0
  171. package/dist/machines/ShareThisComputerForm.js +133 -0
  172. package/dist/machines/TokensPanel.d.ts +5 -3
  173. package/dist/machines/TokensPanel.js +98 -78
  174. package/dist/machines/headless/fixture-host.d.ts +19 -3
  175. package/dist/machines/headless/fixture-host.js +42 -5
  176. package/dist/machines/headless/fixtures.js +4 -6
  177. package/dist/machines/headless/host.d.ts +40 -19
  178. package/dist/machines/headless/index.d.ts +3 -3
  179. package/dist/machines/headless/index.js +2 -2
  180. package/dist/machines/headless/labels.d.ts +63 -20
  181. package/dist/machines/headless/labels.js +88 -25
  182. package/dist/machines/headless/messages.js +8 -0
  183. package/dist/machines/headless/stores.d.ts +9 -2
  184. package/dist/machines/headless/stores.js +28 -1
  185. package/dist/machines/index.d.ts +7 -3
  186. package/dist/machines/index.js +8 -4
  187. package/dist/machines/testing/contract.d.ts +15 -3
  188. package/dist/machines/testing/contract.js +68 -14
  189. package/dist/motion/grow.d.ts +8 -1
  190. package/dist/motion/grow.js +10 -4
  191. package/dist/onboarding/demos/index.js +1 -1
  192. package/dist/onboarding/headless/labels.d.ts +13 -0
  193. package/dist/onboarding/headless/labels.js +8 -0
  194. package/dist/onboarding/index.js +3 -3
  195. package/dist/onboarding/sources/SourceBrowser.js +11 -7
  196. package/dist/onboarding/steps/ConnectorsStep.js +1 -1
  197. package/dist/onboarding/steps/ImportStep.js +4 -1
  198. package/dist/onboarding/steps/ReadyStep.js +9 -2
  199. package/dist/onboarding/steps/SkillsStep.js +1 -1
  200. package/dist/onboarding/steps/connect/KeyForm.js +6 -2
  201. package/dist/onboarding/steps/connect/ProviderPanel.js +6 -2
  202. package/dist/onboarding/steps/connect/ProviderReady.js +25 -20
  203. package/dist/onboarding/steps/tasks.js +17 -14
  204. package/dist/server/sse-handler.js +141 -19
  205. package/dist/session/ArtifactsPanel.js +39 -17
  206. package/dist/session/PlanTracker.js +12 -7
  207. package/dist/session/ProjectHome.js +13 -11
  208. package/dist/session/RemindersPanel.js +34 -16
  209. package/dist/session/RunningWorkDialog.js +6 -2
  210. package/dist/session/SecretsPanel.js +29 -10
  211. package/dist/session/SessionDetailsDialog.d.ts +1 -1
  212. package/dist/session/SessionDetailsDialog.js +18 -10
  213. package/dist/session/SideChat.js +10 -7
  214. package/dist/session/TurnDetailsDialog.js +19 -5
  215. package/dist/session/UsagePanel.js +10 -4
  216. package/dist/session/headless/host.d.ts +2 -0
  217. package/dist/session/headless/labels.d.ts +19 -1
  218. package/dist/session/headless/labels.js +15 -1
  219. package/dist/session/headless/queue.js +2 -1
  220. package/dist/session/headless/reminder-labels.d.ts +4 -0
  221. package/dist/session/headless/reminder-labels.js +4 -0
  222. package/dist/settings/SettingsRestricted.d.ts +1 -1
  223. package/dist/settings/SettingsRestricted.js +4 -4
  224. package/dist/settings/SettingsShell.d.ts +7 -0
  225. package/dist/settings/SettingsShell.js +6 -1
  226. package/dist/settings/headless/fixture-performance.d.ts +1 -1
  227. package/dist/settings/headless/host.d.ts +2 -2
  228. package/dist/settings/headless/labels.d.ts +3 -3
  229. package/dist/settings/headless/labels.js +3 -3
  230. package/dist/settings/headless/performance.d.ts +3 -4
  231. package/dist/settings/headless/search.d.ts +1 -1
  232. package/dist/settings/index.d.ts +2 -1
  233. package/dist/settings/index.js +2 -1
  234. package/dist/settings/sections/editor/EditorSection.js +7 -4
  235. package/dist/settings/sections/editor/labels.d.ts +1 -0
  236. package/dist/settings/sections/editor/labels.js +1 -0
  237. package/dist/settings/sections/environments/EnvironmentsSection.js +19 -12
  238. package/dist/settings/sections/environments/labels.d.ts +1 -0
  239. package/dist/settings/sections/environments/labels.js +2 -1
  240. package/dist/settings/sections/extensions/ExtensionConfigRows.d.ts +1 -3
  241. package/dist/settings/sections/extensions/ExtensionConfigRows.js +20 -19
  242. package/dist/settings/sections/extensions/ExtensionOptionsSection.js +2 -1
  243. package/dist/settings/sections/extensions/options-labels.d.ts +2 -1
  244. package/dist/settings/sections/extensions/options-labels.js +2 -1
  245. package/dist/settings/sections/index.d.ts +2 -1
  246. package/dist/settings/sections/index.js +2 -1
  247. package/dist/settings/sections/logs/LogsSection.d.ts +2 -2
  248. package/dist/settings/sections/logs/LogsSection.js +2 -2
  249. package/dist/settings/sections/mcp/McpSection.d.ts +1 -1
  250. package/dist/settings/sections/mcp/McpSection.js +12 -6
  251. package/dist/settings/sections/mcp/McpServerRow.js +20 -13
  252. package/dist/settings/sections/mcp/labels.d.ts +8 -2
  253. package/dist/settings/sections/mcp/labels.js +8 -2
  254. package/dist/settings/sections/models/ModelRows.js +1 -1
  255. package/dist/settings/sections/models/NewChatPlaceRow.d.ts +26 -0
  256. package/dist/settings/sections/models/NewChatPlaceRow.js +78 -0
  257. package/dist/settings/sections/models/SpacesDefaultsSection.js +15 -3
  258. package/dist/settings/sections/models/labels.d.ts +7 -0
  259. package/dist/settings/sections/models/labels.js +7 -0
  260. package/dist/settings/sections/models/model-test.js +7 -4
  261. package/dist/settings/sections/performance/PerformanceSection.js +16 -6
  262. package/dist/settings/sections/performance/labels.d.ts +1 -1
  263. package/dist/settings/sections/performance/labels.js +1 -1
  264. package/dist/settings/sections/providers/ProvidersSection.d.ts +1 -1
  265. package/dist/settings/sections/providers/ProvidersSection.js +14 -7
  266. package/dist/settings/sections/providers/ServerProvidersSection.d.ts +1 -1
  267. package/dist/settings/sections/providers/ServerProvidersSection.js +11 -5
  268. package/dist/settings/sections/providers/labels.d.ts +2 -2
  269. package/dist/settings/sections/providers/labels.js +2 -2
  270. package/dist/settings/sections/skills/SkillList.js +1 -1
  271. package/dist/settings/sections/skills/SkillsSection.js +1 -1
  272. package/dist/settings/testing/performance.contract.js +8 -12
  273. package/dist/styles.css +32 -3
  274. package/dist/terminal/HostTerminalSurface.js +15 -5
  275. package/dist/terminal/TerminalPanel.js +30 -17
  276. package/dist/terminal/TerminalSurface.js +11 -4
  277. package/dist/terminal/headless/labels.d.ts +5 -0
  278. package/dist/terminal/headless/labels.js +5 -0
  279. package/dist/terminal/headless/store.d.ts +1 -1
  280. package/dist/terminal/headless/store.js +6 -3
  281. package/dist/workspace/LayoutBudget.d.ts +5 -1
  282. package/dist/workspace/LayoutBudget.js +14 -1
  283. package/dist/workspace/PanelContentView.d.ts +1 -1
  284. package/dist/workspace/PanelContentView.js +17 -6
  285. package/dist/workspace/WorkspaceProvider.js +3 -2
  286. package/dist/workspace/headless/labels.d.ts +1 -0
  287. package/dist/workspace/headless/labels.js +1 -0
  288. package/package.json +3 -3
  289. package/src/styles/motion.css +8 -0
  290. package/src/styles/primitives.css +7 -0
@@ -1,5 +1,7 @@
1
1
  import { buttonClass } from "../components/button.js";
2
+ import { Notice } from "../components/Notice.js";
2
3
  import { MetaChip } from "../components/Form.js";
4
+ import { errorMessage } from "../components/report-error.js";
3
5
  import { compactPath } from "../path.js";
4
6
  import { useDisplayPath } from "../hooks/useDisplayPath.js";
5
7
  import { gitErrorText } from "./headless/labels.js";
@@ -71,9 +73,12 @@ function ImportRepoDialog({ clone, initialParent, pickFolder, hostId, onDone, on
71
73
  try {
72
74
  const result = await clone.clone(input, parent);
73
75
  if (result.ok) onDone(result.path);
74
- else if (!("cancelled" in result)) setError(gitErrorText(result.error, labels));
76
+ else if (!("cancelled" in result)) setError({ message: gitErrorText(result.error, labels) });
75
77
  } catch (err) {
76
- setError(err instanceof Error ? err.message : String(err));
78
+ setError({
79
+ message: labels.gitImportFailed,
80
+ detail: errorMessage(err)
81
+ });
77
82
  } finally {
78
83
  setCloning(false);
79
84
  }
@@ -133,10 +138,14 @@ function ImportRepoDialog({ clone, initialParent, pickFolder, hostId, onDone, on
133
138
  "aria-invalid": invalid || void 0,
134
139
  className: "zg-well w-full h-8 px-2.5 font-mono text-zg-label placeholder:text-[var(--zg-text-subtle)] disabled:opacity-zg-disabled"
135
140
  }),
136
- /* @__PURE__ */ jsx("span", {
137
- className: `zg-meta min-h-4 truncate ${invalid ? "!text-zg-danger" : ""}`,
141
+ invalid ? /* @__PURE__ */ jsx(Notice, {
142
+ tone: "error",
143
+ compact: true,
144
+ children: labels.gitImportInvalid
145
+ }) : /* @__PURE__ */ jsx("span", {
146
+ className: "zg-meta min-h-4 truncate",
138
147
  "aria-live": "polite",
139
- children: invalid ? labels.gitImportInvalid : spec ? labels.gitImportPreview(spec.label, spec.branch, compactPath(display.path(joinPath(parent, spec.name), hostId), 44)) : ""
148
+ children: spec ? labels.gitImportPreview(spec.label, spec.branch, compactPath(display.path(joinPath(parent, spec.name), hostId), 44)) : ""
140
149
  })
141
150
  ]
142
151
  }),
@@ -182,10 +191,10 @@ function ImportRepoDialog({ clone, initialParent, pickFolder, hostId, onDone, on
182
191
  children: progress ? labels.gitImportProgress(progress.phase, progress.percent) : labels.gitImportConnecting
183
192
  })]
184
193
  }),
185
- error && /* @__PURE__ */ jsx("div", {
186
- role: "alert",
187
- className: "text-zg-label leading-relaxed text-zg-danger zg-pretty",
188
- children: error
194
+ error && /* @__PURE__ */ jsx(Notice, {
195
+ tone: "error",
196
+ ...error.detail ? { detail: error.detail } : {},
197
+ children: error.message
189
198
  }),
190
199
  /* @__PURE__ */ jsx("button", {
191
200
  type: "submit",
@@ -1,5 +1,7 @@
1
1
  import { buttonClass } from "../components/button.js";
2
+ import { Notice } from "../components/Notice.js";
2
3
  import { Checkbox, MetaChip } from "../components/Form.js";
4
+ import { errorMessage } from "../components/report-error.js";
3
5
  import { MenuNote, MenuRow } from "../components/Menu.js";
4
6
  import { compactPath } from "../path.js";
5
7
  import { useDisplayPath } from "../hooks/useDisplayPath.js";
@@ -77,7 +79,10 @@ function MoveSessionDialog({ subject, onDone, onCancel, className, style }) {
77
79
  }).catch((err) => {
78
80
  if (!live) return;
79
81
  setChoices([]);
80
- setError(err instanceof Error ? err.message : String(err));
82
+ setError({
83
+ message: labels.gitMoveListFailed,
84
+ detail: errorMessage(err)
85
+ });
81
86
  });
82
87
  return () => {
83
88
  live = false;
@@ -120,11 +125,14 @@ function MoveSessionDialog({ subject, onDone, onCancel, className, style }) {
120
125
  ...folder !== null ? { cwd: folder } : {},
121
126
  ...offersRemoval && removeWorktree ? { removeOldWorktree: true } : {}
122
127
  });
123
- if (!result.ok) setError(gitErrorText(result.error, labels));
128
+ if (!result.ok) setError({ message: gitErrorText(result.error, labels) });
124
129
  else if (result.oldWorktree?.removed === false) setKept(result.oldWorktree.reason !== void 0 ? { reason: result.oldWorktree.reason } : {});
125
130
  else onDone();
126
131
  } catch (err) {
127
- setError(err instanceof Error ? err.message : String(err));
132
+ setError({
133
+ message: labels.gitMoveFailed,
134
+ detail: errorMessage(err)
135
+ });
128
136
  } finally {
129
137
  setMoving(false);
130
138
  }
@@ -245,10 +253,10 @@ function MoveSessionDialog({ subject, onDone, onCancel, className, style }) {
245
253
  "data-testid": "move-worktree-kept",
246
254
  children: labels.gitMoveWorktreeKept(kept.reason)
247
255
  }),
248
- error && /* @__PURE__ */ jsx("div", {
249
- role: "alert",
250
- className: "text-zg-label leading-relaxed text-zg-danger zg-pretty",
251
- children: error
256
+ error && /* @__PURE__ */ jsx(Notice, {
257
+ tone: "error",
258
+ ...error.detail ? { detail: error.detail } : {},
259
+ children: error.message
252
260
  })
253
261
  ]
254
262
  }), /* @__PURE__ */ jsx("footer", {
@@ -1,4 +1,6 @@
1
1
  import { IconButton } from "../components/IconButton.js";
2
+ import { Notice } from "../components/Notice.js";
3
+ import { errorMessage } from "../components/report-error.js";
2
4
  import { Menu, MenuNote, MenuRow, MenuSection, MenuSeparator, focusMenuRow } from "../components/Menu.js";
3
5
  import { Popover } from "../components/floating/Popover.js";
4
6
  import { folderName } from "./headless/environment.js";
@@ -132,9 +134,12 @@ function RemoteFolderBrowser({ hostId, machineId, start, onUse, className, style
132
134
  }).then((result) => {
133
135
  if (cancelled) return;
134
136
  if (result.ok) setListing(result.listing);
135
- else setError(gitErrorText(result.error, labels));
137
+ else setError({ message: gitErrorText(result.error, labels) });
136
138
  }).catch((err) => {
137
- if (!cancelled) setError(err instanceof Error ? err.message : String(err));
139
+ if (!cancelled) setError({
140
+ message: labels.gitFolderListFailed,
141
+ detail: errorMessage(err)
142
+ });
138
143
  });
139
144
  return () => {
140
145
  cancelled = true;
@@ -148,9 +153,12 @@ function RemoteFolderBrowser({ hostId, machineId, start, onUse, className, style
148
153
  if (!list) return null;
149
154
  if (error) return /* @__PURE__ */ jsxs(Menu, {
150
155
  ...menuProps,
151
- children: [/* @__PURE__ */ jsx(MenuNote, {
152
- icon: "i-ph-warning",
153
- children: error
156
+ children: [/* @__PURE__ */ jsx(Notice, {
157
+ tone: "error",
158
+ compact: true,
159
+ className: "m-1",
160
+ ...error.detail ? { detail: error.detail } : {},
161
+ children: error.message
154
162
  }), path !== null && /* @__PURE__ */ jsx(MenuRow, {
155
163
  role: "menuitem",
156
164
  icon: /* @__PURE__ */ jsx("span", {
@@ -192,13 +200,16 @@ function RemoteFolderBrowser({ hostId, machineId, start, onUse, className, style
192
200
  } : {
193
201
  query,
194
202
  state: "failed",
195
- error: gitErrorText(result.error, labels)
203
+ error: { message: gitErrorText(result.error, labels) }
196
204
  });
197
205
  }).catch((err) => {
198
206
  setSearch((current) => current?.query !== query ? current : {
199
207
  query,
200
208
  state: "failed",
201
- error: err instanceof Error ? err.message : String(err)
209
+ error: {
210
+ message: labels.gitFolderSearchFailed,
211
+ detail: errorMessage(err)
212
+ }
202
213
  });
203
214
  });
204
215
  };
@@ -226,8 +237,11 @@ function RemoteFolderBrowser({ hostId, machineId, start, onUse, className, style
226
237
  name
227
238
  }).then((result) => {
228
239
  if (result.ok) open(result.folder.path);
229
- else setCreateError(gitErrorText(result.error, labels));
230
- }).catch((err) => setCreateError(err instanceof Error ? err.message : String(err))).finally(() => setCreating(false));
240
+ else setCreateError({ message: gitErrorText(result.error, labels) });
241
+ }).catch((err) => setCreateError({
242
+ message: labels.gitFolderCreateFailed,
243
+ detail: errorMessage(err)
244
+ })).finally(() => setCreating(false));
231
245
  };
232
246
  const crumbs = crumbsOf(listing);
233
247
  return /* @__PURE__ */ jsxs(Menu, {
@@ -332,9 +346,12 @@ function RemoteFolderBrowser({ hostId, machineId, start, onUse, className, style
332
346
  label: labels.gitFolderSearchResults,
333
347
  children: [
334
348
  search.state === "running" && /* @__PURE__ */ jsx(MenuNote, { children: labels.gitFolderSearching }),
335
- search.state === "failed" && /* @__PURE__ */ jsx(MenuNote, {
336
- icon: "i-ph-warning",
337
- children: search.error
349
+ search.state === "failed" && /* @__PURE__ */ jsx(Notice, {
350
+ tone: "error",
351
+ compact: true,
352
+ className: "m-1",
353
+ ...search.error.detail ? { detail: search.error.detail } : {},
354
+ children: search.error.message
338
355
  }),
339
356
  search.state === "done" && /* @__PURE__ */ jsxs(Fragment, { children: [
340
357
  search.results.map((dir) => /* @__PURE__ */ jsx(MenuRow, {
@@ -405,10 +422,11 @@ function RemoteFolderBrowser({ hostId, machineId, start, onUse, className, style
405
422
  }
406
423
  })
407
424
  ]
408
- }), createError && /* @__PURE__ */ jsx("span", {
409
- role: "alert",
410
- className: "text-xs text-[var(--zg-danger)] px-1",
411
- children: createError
425
+ }), createError && /* @__PURE__ */ jsx(Notice, {
426
+ tone: "error",
427
+ compact: true,
428
+ ...createError.detail ? { detail: createError.detail } : {},
429
+ children: createError.message
412
430
  })]
413
431
  })),
414
432
  /* @__PURE__ */ jsx(MenuSeparator, {}),
@@ -1,5 +1,7 @@
1
1
  import { BTN_SECONDARY, buttonClass } from "../components/button.js";
2
+ import { Notice } from "../components/Notice.js";
2
3
  import { Tooltip } from "../components/Tooltip.js";
4
+ import { errorMessage } from "../components/report-error.js";
3
5
  import { FloatingSurface } from "../components/floating/FloatingSurface.js";
4
6
  import { RollingText } from "../motion/roll.js";
5
7
  import { gitErrorText } from "./headless/labels.js";
@@ -76,14 +78,15 @@ function SyncChip({ status, cwd, sessionId, running, onSynced, confirm = true, o
76
78
  if (dontAsk) onConfirmChange?.(false);
77
79
  setBusy(true);
78
80
  try {
79
- const result = await host.sync(cwd, sessionId).catch((err) => ({
80
- ok: false,
81
- error: {
82
- code: "failed",
83
- message: err instanceof Error ? err.message : String(err)
84
- }
85
- }));
86
- if (!result.ok) setPopover({
81
+ const result = await host.sync(cwd, sessionId).catch((err) => {
82
+ setPopover({
83
+ kind: "error",
84
+ message: labels.gitSyncFailed,
85
+ detail: errorMessage(err)
86
+ });
87
+ return null;
88
+ });
89
+ if (result && !result.ok) setPopover({
87
90
  kind: "error",
88
91
  message: gitErrorText(result.error, labels)
89
92
  });
@@ -218,17 +221,14 @@ function SyncChip({ status, cwd, sessionId, running, onSynced, confirm = true, o
218
221
  })
219
222
  ]
220
223
  })]
221
- }), popover?.kind === "error" && /* @__PURE__ */ jsxs("div", {
222
- role: "alert",
224
+ }), popover?.kind === "error" && /* @__PURE__ */ jsx("div", {
223
225
  "data-testid": "git-sync-error",
224
- className: "flex items-start gap-2 p-3 text-zg-label leading-[1.45] text-[var(--zg-text)]",
225
- children: [/* @__PURE__ */ jsx("span", {
226
- "aria-hidden": true,
227
- className: "i-ph-warning text-zg-ui shrink-0 mt-[2px] text-zg-danger"
228
- }), /* @__PURE__ */ jsx("span", {
229
- className: "min-w-0 zg-pretty",
226
+ className: "p-1.5",
227
+ children: /* @__PURE__ */ jsx(Notice, {
228
+ tone: "error",
229
+ ...popover.detail ? { detail: popover.detail } : {},
230
230
  children: popover.message
231
- })]
231
+ })
232
232
  })]
233
233
  })]
234
234
  });
@@ -1,5 +1,5 @@
1
1
  import { HostView } from "../chat/headless/hosts.js";
2
- import { DraftEnvironment } from "./headless/environment.js";
2
+ import { DraftEnvironment, EnvironmentMachine } from "./headless/environment.js";
3
3
  import { CSSProperties } from "react";
4
4
  import { EnvironmentDescriptor } from "zidane/chat";
5
5
  //#region src/git/WherePicker.d.ts
@@ -19,6 +19,21 @@ interface WhereMenuProps {
19
19
  onChange: (next: DraftEnvironment) => void;
20
20
  /** Machine names not to list (servers this computer also uses as machines, shown as servers). */
21
21
  hiddenMachines?: ReadonlySet<string>;
22
+ /** The machines of the other hosts, by host id. Absent: only the draft host's machines show. */
23
+ serverMachines?: ReadonlyMap<string, readonly EnvironmentMachine[]>;
24
+ /** Called with a machine of another host (from {@link WhereMenuProps.serverMachines}): the draft moves there. */
25
+ onPickServerMachine?: (hostId: string, machine: EnvironmentMachine) => void;
26
+ /** Opens Add a machine for a server. Absent: no Add a machine row. */
27
+ onAddMachine?: (hostId: string) => void;
28
+ /**
29
+ * "Use for new chats": whether the draft's place is where new chats start now, the space whose default it sets
30
+ * (absent: the global one), and what a pick does (set it, or clear it when it is the default). Absent: no row.
31
+ */
32
+ newChatsDefault?: {
33
+ isDefault: boolean;
34
+ space?: string;
35
+ onToggle: () => void;
36
+ };
22
37
  /** Opens the environment settings. Absent: no settings row. */
23
38
  onOpenSettings?: () => void;
24
39
  /** Called after a pick that ends the choice (the popover closes). */
@@ -7,7 +7,7 @@ import { useGitLabels } from "./GitProvider.js";
7
7
  import { hostReachable, hostStatusLabel } from "../chat/headless/hosts.js";
8
8
  import { HostBadge } from "../chat/HostBadge.js";
9
9
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
- import { useRef } from "react";
10
+ import { Fragment as Fragment$1, useRef } from "react";
11
11
  import { isolationLabel, parseMachineKind } from "zidane/chat/pure";
12
12
  //#region src/git/WherePicker.tsx
13
13
  /**
@@ -15,10 +15,13 @@ import { isolationLabel, parseMachineKind } from "zidane/chat/pure";
15
15
  * in one place:
16
16
  *
17
17
  * - **Runs on**: this computer, a saved server (the session lives there and
18
- * keeps running with the app closed), or a machine shared with the draft's
19
- * host (the session stays on the host, the files and commands are on the
20
- * machine). A server this computer also uses as a machine shows once, as
21
- * the server (`hiddenMachines`).
18
+ * keeps running with the app closed), or a machine of one of them (the
19
+ * session stays on that host, the files and commands are on the machine).
20
+ * Each host's machines sit under it: the draft host's from its kinds, the
21
+ * other servers' from `serverMachines`, so one pick moves the draft to a
22
+ * machine of any server. An offline machine stays pickable (the chat waits
23
+ * for it). A server this computer also uses as a machine shows once, as the
24
+ * server (`hiddenMachines`).
22
25
  * - **Isolation** on that place: in the folder, a new worktree (with its
23
26
  * branch), or a sandbox kind the host offers (Docker, E2B, Daytona…).
24
27
  *
@@ -100,7 +103,7 @@ function RunsOnHelp({ labels }) {
100
103
  * @param props - Component props.
101
104
  */
102
105
  function WhereMenu(props) {
103
- const { hosts, hostId, onHostChange, descriptors, onChange, onOpenSettings, onClose, className, style } = props;
106
+ const { hosts, hostId, onHostChange, descriptors, onChange, onOpenSettings, onClose, serverMachines, onPickServerMachine, onAddMachine, newChatsDefault, className, style } = props;
104
107
  const labels = useGitLabels();
105
108
  const branchRef = useRef(null);
106
109
  const { host, machines, selected, machine, isolations, typedBranch } = resolveWhere(props);
@@ -114,7 +117,12 @@ function WhereMenu(props) {
114
117
  });
115
118
  close();
116
119
  };
117
- const pickMachine = (next) => {
120
+ const pickMachine = (owner, next) => {
121
+ if (owner.id !== host.id) {
122
+ onPickServerMachine?.(owner.id, next);
123
+ close();
124
+ return;
125
+ }
118
126
  const own = descriptors.filter((d) => d.machine?.id === next.id && d.enabled && d.available);
119
127
  const kind = (own.find((d) => parseMachineKind(d.kind)?.base === "local") ?? own[0])?.kind;
120
128
  if (kind) onChange({
@@ -123,6 +131,7 @@ function WhereMenu(props) {
123
131
  });
124
132
  close();
125
133
  };
134
+ const machinesUnder = (h) => h.id === host.id ? machines : onPickServerMachine && hostReachable(h) ? serverMachines?.get(h.id) ?? [] : [];
126
135
  return /* @__PURE__ */ jsxs("div", {
127
136
  role: "group",
128
137
  "aria-label": labels.gitWhereLabel,
@@ -146,38 +155,54 @@ function WhereMenu(props) {
146
155
  className: "i-ph-question text-zg-label text-[var(--zg-text-subtle)] hover:text-[var(--zg-text-muted)] cursor-help outline-none focus-visible:text-[var(--zg-text)]"
147
156
  })
148
157
  }),
149
- children: /* @__PURE__ */ jsxs("div", {
158
+ children: /* @__PURE__ */ jsx("div", {
150
159
  role: "menu",
151
160
  "aria-label": labels.gitRunsOn,
152
- children: [hosts.map((h) => /* @__PURE__ */ jsx(MenuRow, {
153
- size: "lg",
154
- role: "menuitemradio",
155
- checked: !machine && h.id === host.id,
156
- disabled: !hostReachable(h),
157
- icon: /* @__PURE__ */ jsx("span", {
158
- "aria-hidden": true,
159
- className: placeIcon(h.kind)
160
- }),
161
- title: /* @__PURE__ */ jsx(HostBadge, { host: h }),
162
- description: h.kind === "local" ? labels.gitHostLocalDescription : hostReachable(h) ? labels.gitHostServerDescription : hostStatusLabel(h),
163
- onClick: () => pickHost(h)
164
- }, h.id)), machines.map((m) => /* @__PURE__ */ jsx(MenuRow, {
165
- size: "lg",
166
- role: "menuitemradio",
167
- checked: machine?.id === m.id,
168
- disabled: m.status !== "online",
169
- icon: /* @__PURE__ */ jsx("span", {
170
- "aria-hidden": true,
171
- className: placeIcon("machine")
161
+ children: hosts.map((h) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
162
+ /* @__PURE__ */ jsx(MenuRow, {
163
+ size: "lg",
164
+ role: "menuitemradio",
165
+ checked: !machine && h.id === host.id,
166
+ disabled: !hostReachable(h),
167
+ icon: /* @__PURE__ */ jsx("span", {
168
+ "aria-hidden": true,
169
+ className: placeIcon(h.kind)
170
+ }),
171
+ title: /* @__PURE__ */ jsx(HostBadge, { host: h }),
172
+ description: h.kind === "local" ? labels.gitHostLocalDescription : hostReachable(h) ? labels.gitHostServerDescription : hostStatusLabel(h),
173
+ onClick: () => pickHost(h)
172
174
  }),
173
- title: /* @__PURE__ */ jsxs(Fragment, { children: [m.name, /* @__PURE__ */ jsx(MetaChip, {
174
- tone: m.status === "online" ? "success" : "muted",
175
- className: "font-normal ml-1.5",
176
- children: labels.gitMachineStatus(m.status)
177
- })] }),
178
- description: m.status === "online" ? labels.gitMachineDescription(m.name) : labels.gitMachineOffline(m.name),
179
- onClick: () => pickMachine(m)
180
- }, m.id))]
175
+ machinesUnder(h).map((m) => /* @__PURE__ */ jsx(MenuRow, {
176
+ size: "lg",
177
+ role: "menuitemradio",
178
+ className: "zg-menu-row-nested",
179
+ checked: h.id === host.id && machine?.id === m.id,
180
+ icon: /* @__PURE__ */ jsx("span", {
181
+ "aria-hidden": true,
182
+ className: placeIcon("machine")
183
+ }),
184
+ title: /* @__PURE__ */ jsxs(Fragment, { children: [m.name, m.status !== "online" && /* @__PURE__ */ jsx(MetaChip, {
185
+ tone: "muted",
186
+ className: "font-normal ml-1.5",
187
+ children: labels.gitMachineStatus(m.status)
188
+ })] }),
189
+ description: m.status !== "online" ? labels.gitMachineOfflineWaits(m.name) : h.kind === "local" ? labels.gitMachineDescription(m.name) : labels.gitMachineDescription(m.name, h.name),
190
+ onClick: () => pickMachine(h, m)
191
+ }, m.id)),
192
+ onAddMachine && h.kind === "server" && hostReachable(h) && /* @__PURE__ */ jsx(MenuRow, {
193
+ role: "menuitem",
194
+ className: "zg-menu-row-nested",
195
+ icon: /* @__PURE__ */ jsx("span", {
196
+ "aria-hidden": true,
197
+ className: "i-ph-plus"
198
+ }),
199
+ title: labels.gitAddMachine,
200
+ onClick: () => {
201
+ close();
202
+ onAddMachine(h.id);
203
+ }
204
+ })
205
+ ] }, h.id))
181
206
  })
182
207
  }),
183
208
  isolations.length > 1 && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(MenuSeparator, {}), /* @__PURE__ */ jsx(MenuSection, {
@@ -244,6 +269,25 @@ function WhereMenu(props) {
244
269
  icon: "i-ph-info",
245
270
  children: selected.note
246
271
  }),
272
+ machine && machine.status !== "online" && /* @__PURE__ */ jsx(MenuNote, {
273
+ icon: "i-ph-clock",
274
+ children: labels.gitMachineOfflineNote(machine.name)
275
+ }),
276
+ newChatsDefault && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(MenuSeparator, {}), /* @__PURE__ */ jsx("div", {
277
+ role: "menu",
278
+ "aria-label": labels.gitNewChatsDefault,
279
+ children: /* @__PURE__ */ jsx(MenuRow, {
280
+ role: "menuitemcheckbox",
281
+ toggle: newChatsDefault.isDefault,
282
+ icon: /* @__PURE__ */ jsx("span", {
283
+ "aria-hidden": true,
284
+ className: "i-ph-push-pin"
285
+ }),
286
+ title: newChatsDefault.space ? labels.gitUseForNewChatsIn(newChatsDefault.space) : labels.gitUseForNewChats,
287
+ ...newChatsDefault.isDefault ? { description: labels.gitNewChatsStartHere } : {},
288
+ onClick: newChatsDefault.onToggle
289
+ })
290
+ })] }),
247
291
  onOpenSettings && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(MenuSeparator, {}), /* @__PURE__ */ jsx("div", {
248
292
  role: "menu",
249
293
  "aria-label": labels.gitEnvironmentSettings,
@@ -1,3 +1,4 @@
1
+ import { NewChatPlace } from "zidane/chat/pure";
1
2
  import { EnvironmentCheckout, EnvironmentDescriptor, EnvironmentRequest } from "zidane/chat";
2
3
  //#region src/git/headless/environment.d.ts
3
4
  /** What the user picked in a draft; `null` where it is used = the configured default. */
@@ -20,13 +21,23 @@ type EnvironmentMachine = NonNullable<EnvironmentDescriptor['machine']>;
20
21
  * @param kind - The environment kind.
21
22
  */
22
23
  declare function environmentKindIcon(kind: string): string;
24
+ /** Options of {@link withMachines}. */
25
+ interface WithMachinesOptions {
26
+ /**
27
+ * An offline machine's kinds stay usable: a new chat there starts and waits until the machine is back (the
28
+ * host provisions it in the background). Default false: unavailable, with the reason (moving a session needs
29
+ * the machine now).
30
+ */
31
+ offlineWaits?: boolean;
32
+ }
23
33
  /**
24
34
  * A machine's kinds after this host's, grouped by machine; an offline machine's stay listed,
25
- * unavailable with the reason.
35
+ * unavailable with the reason unless {@link WithMachinesOptions.offlineWaits}.
26
36
  *
27
37
  * @param descriptors - The kinds the host lists.
38
+ * @param options - Whether an offline machine's kinds stay usable.
28
39
  */
29
- declare function withMachines(descriptors: readonly EnvironmentDescriptor[]): EnvironmentDescriptor[];
40
+ declare function withMachines(descriptors: readonly EnvironmentDescriptor[], options?: WithMachinesOptions): EnvironmentDescriptor[];
30
41
  /**
31
42
  * The descriptor a draft resolves to: the pick when still usable, else the default, else Local.
32
43
  * `undefined` when nothing is loaded yet.
@@ -61,5 +72,24 @@ declare function environmentBaseKind(kind: string): string;
61
72
  * @param path - A `/` or `\` separated path.
62
73
  */
63
74
  declare function folderName(path: string): string;
75
+ /**
76
+ * A machine's environment kind (`local@gpu`, `worktree@gpu`).
77
+ *
78
+ * @param machine - The machine's name.
79
+ * @param base - Its folder (`local`) or a new worktree there.
80
+ */
81
+ declare function machineEnvironmentKind(machine: string, base?: 'local' | 'worktree'): string;
82
+ /**
83
+ * The machine an environment kind runs on (`worktree@gpu` → `gpu`); `undefined` for the host's own kinds.
84
+ *
85
+ * @param kind - The environment kind.
86
+ */
87
+ declare function environmentMachineName(kind: string): string | undefined;
88
+ /**
89
+ * The environment kind a default place asks for (`worktree@gpu`, `docker`); `undefined` for the host's default.
90
+ *
91
+ * @param place - Where new chats start.
92
+ */
93
+ declare function newChatPlaceKind(place: Pick<NewChatPlace, 'machine' | 'isolation'>): string | undefined;
64
94
  //#endregion
65
- export { DraftEnvironment, EnvironmentMachine, environmentBaseKind, environmentKindIcon, folderName, machinesOf, resolveDraftDescriptor, resolveDraftEnvironment, withMachines };
95
+ export { DraftEnvironment, EnvironmentMachine, WithMachinesOptions, environmentBaseKind, environmentKindIcon, environmentMachineName, folderName, machineEnvironmentKind, machinesOf, newChatPlaceKind, resolveDraftDescriptor, resolveDraftEnvironment, withMachines };
@@ -1,4 +1,4 @@
1
- import { machineBlockedReason, orderByMachine, parseMachineKind } from "zidane/chat/pure";
1
+ import { machineBlockedReason, machineKind, orderByMachine, parseMachineKind, placeEnvironmentKind } from "zidane/chat/pure";
2
2
  //#region src/git/headless/environment.ts
3
3
  const KIND_ICONS = {
4
4
  local: "i-ph-laptop",
@@ -17,12 +17,15 @@ function environmentKindIcon(kind) {
17
17
  }
18
18
  /**
19
19
  * A machine's kinds after this host's, grouped by machine; an offline machine's stay listed,
20
- * unavailable with the reason.
20
+ * unavailable with the reason unless {@link WithMachinesOptions.offlineWaits}.
21
21
  *
22
22
  * @param descriptors - The kinds the host lists.
23
+ * @param options - Whether an offline machine's kinds stay usable.
23
24
  */
24
- function withMachines(descriptors) {
25
- return orderByMachine(descriptors).map((descriptor) => {
25
+ function withMachines(descriptors, options = {}) {
26
+ const ordered = orderByMachine(descriptors);
27
+ if (options.offlineWaits) return ordered;
28
+ return ordered.map((descriptor) => {
26
29
  const blocked = machineBlockedReason(descriptor);
27
30
  return blocked && descriptor.available ? {
28
31
  ...descriptor,
@@ -94,5 +97,30 @@ function folderName(path) {
94
97
  const idx = Math.max(trimmed.lastIndexOf("/"), trimmed.lastIndexOf("\\"));
95
98
  return idx === -1 ? trimmed : trimmed.slice(idx + 1);
96
99
  }
100
+ /**
101
+ * A machine's environment kind (`local@gpu`, `worktree@gpu`).
102
+ *
103
+ * @param machine - The machine's name.
104
+ * @param base - Its folder (`local`) or a new worktree there.
105
+ */
106
+ function machineEnvironmentKind(machine, base = "local") {
107
+ return machineKind(base, machine);
108
+ }
109
+ /**
110
+ * The machine an environment kind runs on (`worktree@gpu` → `gpu`); `undefined` for the host's own kinds.
111
+ *
112
+ * @param kind - The environment kind.
113
+ */
114
+ function environmentMachineName(kind) {
115
+ return parseMachineKind(kind)?.name;
116
+ }
117
+ /**
118
+ * The environment kind a default place asks for (`worktree@gpu`, `docker`); `undefined` for the host's default.
119
+ *
120
+ * @param place - Where new chats start.
121
+ */
122
+ function newChatPlaceKind(place) {
123
+ return placeEnvironmentKind(place);
124
+ }
97
125
  //#endregion
98
- export { environmentBaseKind, environmentKindIcon, folderName, machinesOf, resolveDraftDescriptor, resolveDraftEnvironment, withMachines };
126
+ export { environmentBaseKind, environmentKindIcon, environmentMachineName, folderName, machineEnvironmentKind, machinesOf, newChatPlaceKind, resolveDraftDescriptor, resolveDraftEnvironment, withMachines };
@@ -1,8 +1,8 @@
1
1
  import { GitActionResult, GitBranch, GitBranchPullRequest, GitCheckoutResult, GitCheckoutTarget, GitClone, GitCloneProgress, GitCloneResult, GitCreateFolderQuery, GitCreateFolderResult, GitEnvironmentQuery, GitFolderAllows, GitFolderEntry, GitFolderListing, GitFolderQuery, GitFolderResult, GitFolderSearchQuery, GitFolderSearchResult, GitHost, GitHostError, GitMoveResult, GitMoveTarget, GitPullRequest, GitPullRequestList, GitPullRequestQuery, GitRepoInfo, GitRepoSpec, GitStatus, GitSyncResult } from "./host.js";
2
- import { DraftEnvironment, EnvironmentMachine, environmentBaseKind, environmentKindIcon, folderName, machinesOf, resolveDraftDescriptor, resolveDraftEnvironment, withMachines } from "./environment.js";
2
+ import { DraftEnvironment, EnvironmentMachine, WithMachinesOptions, environmentBaseKind, environmentKindIcon, environmentMachineName, folderName, machineEnvironmentKind, machinesOf, newChatPlaceKind, resolveDraftDescriptor, resolveDraftEnvironment, withMachines } from "./environment.js";
3
3
  import { DraftRemoteClone, resolveRemoteClone } from "./remote-clone.js";
4
4
  import { DEFAULT_GIT_LABELS, GitLabels, gitErrorText } from "./labels.js";
5
5
  import { MoveChoice, MoveSessionSubject, leavesWorktree, moveChoices, moveListingCwd, moveSubject } from "./move.js";
6
6
  import { SWITCHER_SECTIONS, SwitcherCache, SwitcherEntry, SwitcherSection, SwitcherSectionId, ageIsDuration, clockTime, compactCount, createSwitcherCache, prMatches, readPullRequests, switcherCacheOf, switcherCreates, switcherKey, switcherSections } from "./switcher.js";
7
7
  import { GitSyncAction, syncAction, syncSummary, syncTooltip } from "./sync.js";
8
- export { DEFAULT_GIT_LABELS, DraftEnvironment, DraftRemoteClone, EnvironmentMachine, GitActionResult, GitBranch, GitBranchPullRequest, GitCheckoutResult, GitCheckoutTarget, GitClone, GitCloneProgress, GitCloneResult, GitCreateFolderQuery, GitCreateFolderResult, GitEnvironmentQuery, GitFolderAllows, GitFolderEntry, GitFolderListing, GitFolderQuery, GitFolderResult, GitFolderSearchQuery, GitFolderSearchResult, GitHost, GitHostError, GitLabels, GitMoveResult, GitMoveTarget, GitPullRequest, GitPullRequestList, GitPullRequestQuery, GitRepoInfo, GitRepoSpec, GitStatus, GitSyncAction, GitSyncResult, MoveChoice, MoveSessionSubject, SWITCHER_SECTIONS, SwitcherCache, SwitcherEntry, SwitcherSection, SwitcherSectionId, ageIsDuration, clockTime, compactCount, createSwitcherCache, environmentBaseKind, environmentKindIcon, folderName, gitErrorText, leavesWorktree, machinesOf, moveChoices, moveListingCwd, moveSubject, prMatches, readPullRequests, resolveDraftDescriptor, resolveDraftEnvironment, resolveRemoteClone, switcherCacheOf, switcherCreates, switcherKey, switcherSections, syncAction, syncSummary, syncTooltip, withMachines };
8
+ export { DEFAULT_GIT_LABELS, DraftEnvironment, DraftRemoteClone, EnvironmentMachine, GitActionResult, GitBranch, GitBranchPullRequest, GitCheckoutResult, GitCheckoutTarget, GitClone, GitCloneProgress, GitCloneResult, GitCreateFolderQuery, GitCreateFolderResult, GitEnvironmentQuery, GitFolderAllows, GitFolderEntry, GitFolderListing, GitFolderQuery, GitFolderResult, GitFolderSearchQuery, GitFolderSearchResult, GitHost, GitHostError, GitLabels, GitMoveResult, GitMoveTarget, GitPullRequest, GitPullRequestList, GitPullRequestQuery, GitRepoInfo, GitRepoSpec, GitStatus, GitSyncAction, GitSyncResult, MoveChoice, MoveSessionSubject, SWITCHER_SECTIONS, SwitcherCache, SwitcherEntry, SwitcherSection, SwitcherSectionId, WithMachinesOptions, ageIsDuration, clockTime, compactCount, createSwitcherCache, environmentBaseKind, environmentKindIcon, environmentMachineName, folderName, gitErrorText, leavesWorktree, machineEnvironmentKind, machinesOf, moveChoices, moveListingCwd, moveSubject, newChatPlaceKind, prMatches, readPullRequests, resolveDraftDescriptor, resolveDraftEnvironment, resolveRemoteClone, switcherCacheOf, switcherCreates, switcherKey, switcherSections, syncAction, syncSummary, syncTooltip, withMachines };
@@ -1,7 +1,7 @@
1
- import { environmentBaseKind, environmentKindIcon, folderName, machinesOf, resolveDraftDescriptor, resolveDraftEnvironment, withMachines } from "./environment.js";
1
+ import { environmentBaseKind, environmentKindIcon, environmentMachineName, folderName, machineEnvironmentKind, machinesOf, newChatPlaceKind, resolveDraftDescriptor, resolveDraftEnvironment, withMachines } from "./environment.js";
2
2
  import { DEFAULT_GIT_LABELS, gitErrorText } from "./labels.js";
3
3
  import { resolveRemoteClone } from "./remote-clone.js";
4
4
  import { SWITCHER_SECTIONS, ageIsDuration, clockTime, compactCount, createSwitcherCache, prMatches, readPullRequests, switcherCacheOf, switcherCreates, switcherKey, switcherSections } from "./switcher.js";
5
5
  import { syncAction, syncSummary, syncTooltip } from "./sync.js";
6
6
  import { leavesWorktree, moveChoices, moveListingCwd, moveSubject } from "./move.js";
7
- export { DEFAULT_GIT_LABELS, SWITCHER_SECTIONS, ageIsDuration, clockTime, compactCount, createSwitcherCache, environmentBaseKind, environmentKindIcon, folderName, gitErrorText, leavesWorktree, machinesOf, moveChoices, moveListingCwd, moveSubject, prMatches, readPullRequests, resolveDraftDescriptor, resolveDraftEnvironment, resolveRemoteClone, switcherCacheOf, switcherCreates, switcherKey, switcherSections, syncAction, syncSummary, syncTooltip, withMachines };
7
+ export { DEFAULT_GIT_LABELS, SWITCHER_SECTIONS, ageIsDuration, clockTime, compactCount, createSwitcherCache, environmentBaseKind, environmentKindIcon, environmentMachineName, folderName, gitErrorText, leavesWorktree, machineEnvironmentKind, machinesOf, moveChoices, moveListingCwd, moveSubject, newChatPlaceKind, prMatches, readPullRequests, resolveDraftDescriptor, resolveDraftEnvironment, resolveRemoteClone, switcherCacheOf, switcherCreates, switcherKey, switcherSections, syncAction, syncSummary, syncTooltip, withMachines };