zidane-ui 9.1.4 → 9.1.6

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 (251) hide show
  1. package/dist/adapters/server-extensions-host.js +1 -1
  2. package/dist/adapters/server-host.js +2 -1
  3. package/dist/adapters/server-machines-host.js +1 -1
  4. package/dist/adapters/server-session-host.js +87 -13
  5. package/dist/adapters/server-settings-host.js +1 -1
  6. package/dist/appearance/AppearanceProvider.js +2 -2
  7. package/dist/appearance/headless/index.js +1 -1
  8. package/dist/approvals/headless/index.js +2 -2
  9. package/dist/chat/HostTranscript.d.ts +5 -1
  10. package/dist/chat/HostTranscript.js +16 -4
  11. package/dist/chat/RunEstimateChip.d.ts +5 -3
  12. package/dist/chat/RunEstimateChip.js +33 -3
  13. package/dist/chat/Transcript.js +1 -1
  14. package/dist/chat/composer/ConversationBadges.js +16 -10
  15. package/dist/chat/composer/composer-bus.d.ts +2 -2
  16. package/dist/chat/composer/composer-bus.js +2 -2
  17. package/dist/chat/composer/use-composer-stores.js +1 -1
  18. package/dist/chat/composer/use-run-meter.js +1 -1
  19. package/dist/chat/headless/composer/conversation-badges.d.ts +8 -3
  20. package/dist/chat/headless/composer/conversation-badges.js +26 -11
  21. package/dist/chat/headless/composer/index.js +2 -2
  22. package/dist/chat/headless/composer/labels-chrome.d.ts +3 -1
  23. package/dist/chat/headless/composer/labels-chrome.js +3 -1
  24. package/dist/chat/headless/index.d.ts +6 -3
  25. package/dist/chat/headless/index.js +16 -13
  26. package/dist/chat/headless/labels.d.ts +54 -1
  27. package/dist/chat/headless/labels.js +62 -2
  28. package/dist/chat/headless/secrets.d.ts +32 -0
  29. package/dist/chat/headless/secrets.js +43 -0
  30. package/dist/chat/headless/session-list.d.ts +45 -0
  31. package/dist/chat/headless/sidebar/estimates.js +13 -1
  32. package/dist/chat/headless/sidebar/history.d.ts +71 -0
  33. package/dist/chat/headless/sidebar/history.js +174 -0
  34. package/dist/chat/headless/sidebar/index.d.ts +3 -2
  35. package/dist/chat/headless/sidebar/index.js +2 -1
  36. package/dist/chat/headless/sidebar/labels.d.ts +50 -0
  37. package/dist/chat/headless/sidebar/labels.js +1 -0
  38. package/dist/chat/headless/sidebar/query.d.ts +2 -2
  39. package/dist/chat/headless/sidebar/query.js +6 -3
  40. package/dist/chat/headless/sidebar/types.d.ts +7 -1
  41. package/dist/chat/headless/sidebar/view.js +2 -0
  42. package/dist/chat/headless/transcript/auth-failure.d.ts +67 -0
  43. package/dist/chat/headless/transcript/auth-failure.js +87 -0
  44. package/dist/chat/headless/transcript/index.d.ts +2 -1
  45. package/dist/chat/headless/transcript/index.js +2 -1
  46. package/dist/chat/headless/transcript/nesting.d.ts +3 -3
  47. package/dist/chat/headless/transcript/nesting.js +12 -4
  48. package/dist/chat/index.d.ts +4 -2
  49. package/dist/chat/index.js +3 -1
  50. package/dist/chat/interactions/InboxPanel.d.ts +6 -2
  51. package/dist/chat/interactions/InboxPanel.js +82 -44
  52. package/dist/chat/interactions/PlanCard.d.ts +2 -2
  53. package/dist/chat/interactions/PlanCard.js +1 -1
  54. package/dist/chat/interactions/QuestionField.d.ts +8 -3
  55. package/dist/chat/interactions/QuestionField.js +89 -8
  56. package/dist/chat/interactions/QuestionForm.d.ts +3 -1
  57. package/dist/chat/interactions/QuestionForm.js +48 -10
  58. package/dist/chat/interactions/SecretInput.d.ts +32 -0
  59. package/dist/chat/interactions/SecretInput.js +72 -0
  60. package/dist/chat/interactions/card-ui.d.ts +5 -3
  61. package/dist/chat/interactions/card-ui.js +5 -3
  62. package/dist/chat/interactions/index.d.ts +2 -1
  63. package/dist/chat/interactions/index.js +2 -1
  64. package/dist/chat/sidebar/SessionSidebar.js +2 -0
  65. package/dist/chat/sidebar/SidebarFilterMenu.d.ts +7 -2
  66. package/dist/chat/sidebar/SidebarFilterMenu.js +26 -2
  67. package/dist/chat/sidebar/SidebarSessionRow.d.ts +3 -1
  68. package/dist/chat/sidebar/SidebarSessionRow.js +8 -3
  69. package/dist/chat/sidebar/sidebar-live.js +8 -4
  70. package/dist/chat/transcript/AuthFailureCard.d.ts +34 -0
  71. package/dist/chat/transcript/AuthFailureCard.js +358 -0
  72. package/dist/chat/transcript/InteractionToolBody.js +12 -2
  73. package/dist/chat/transcript/actions.d.ts +24 -1
  74. package/dist/chat/transcript/index.d.ts +3 -2
  75. package/dist/chat/transcript/index.js +2 -1
  76. package/dist/chat/transcript/notices.d.ts +2 -1
  77. package/dist/chat/transcript/notices.js +13 -1
  78. package/dist/chat/transcript/script-input.d.ts +1 -1
  79. package/dist/chat/transcript/shell-block.js +1 -1
  80. package/dist/components/HowItWorks.d.ts +8 -1
  81. package/dist/components/HowItWorks.js +2 -2
  82. package/dist/components/RowActionsMenu.d.ts +6 -1
  83. package/dist/components/RowActionsMenu.js +4 -0
  84. package/dist/core.css +24 -0
  85. package/dist/dist/{index-WlE93Q6d.d.ts → index-DqCio7Nd.d.ts} +36 -3
  86. package/dist/dist/index-f-XWIoYo.d.ts +1 -0
  87. package/dist/dist/index.d.ts +6 -0
  88. package/dist/dist/sandbox-B4OW6oNx.d.ts +2 -0
  89. package/dist/dist/timeout-B5pO5I5a.d.ts +30 -0
  90. package/dist/extensions/ExtensionSettingsPage.js +1 -1
  91. package/dist/extensions/ExtensionSettingsSidebar.js +1 -1
  92. package/dist/extensions/headless/fixture-host.js +1 -1
  93. package/dist/extensions/headless/index.js +4 -4
  94. package/dist/extensions/hooks.js +1 -1
  95. package/dist/files/DiffsTab.js +1 -1
  96. package/dist/files/EditorColumn.js +1 -1
  97. package/dist/files/MediaDiff.js +1 -1
  98. package/dist/files/SearchPanel.js +121 -53
  99. package/dist/files/headless/name-match.js +29 -14
  100. package/dist/files/useEntryActions.js +1 -1
  101. package/dist/files/useOpenFiles.js +1 -1
  102. package/dist/git/WherePicker.js +2 -2
  103. package/dist/git/headless/environment.d.ts +6 -1
  104. package/dist/git/headless/environment.js +5 -2
  105. package/dist/git/headless/labels.d.ts +2 -0
  106. package/dist/git/headless/labels.js +2 -0
  107. package/dist/git/index.d.ts +2 -1
  108. package/dist/git/index.js +2 -1
  109. package/dist/git/useStartFromPanel.d.ts +22 -0
  110. package/dist/git/useStartFromPanel.js +91 -0
  111. package/dist/keybindings/KeyCommands.js +1 -1
  112. package/dist/keybindings/KeybindingsProvider.js +1 -1
  113. package/dist/keybindings/headless/catalog.d.ts +1 -1
  114. package/dist/keybindings/headless/catalog.js +14 -2
  115. package/dist/keybindings/headless/index.js +2 -2
  116. package/dist/keybindings/headless/key-scope.d.ts +4 -2
  117. package/dist/keybindings/headless/key-scope.js +17 -2
  118. package/dist/keybindings/headless/overrides.js +1 -1
  119. package/dist/machines/HostSyncPanel.js +1 -1
  120. package/dist/machines/SyncOutcomeBadge.js +1 -1
  121. package/dist/machines/headless/index.js +1 -1
  122. package/dist/onboarding/demos/features.d.ts +9 -1
  123. package/dist/onboarding/demos/features.js +107 -2
  124. package/dist/onboarding/demos/how-it-works.d.ts +5 -1
  125. package/dist/onboarding/demos/how-it-works.js +120 -2
  126. package/dist/onboarding/demos/index.js +1 -1
  127. package/dist/onboarding/headless/labels.d.ts +17 -0
  128. package/dist/onboarding/headless/labels.js +17 -0
  129. package/dist/onboarding/index.js +4 -4
  130. package/dist/onboarding/marks.d.ts +1 -2
  131. package/dist/onboarding/marks.js +4 -12
  132. package/dist/onboarding/steps/ConnectorsStep.js +1 -1
  133. package/dist/onboarding/steps/ReadyStep.js +1 -1
  134. package/dist/onboarding/steps/SkillsStep.js +1 -1
  135. package/dist/onboarding/steps/connect/ProviderPanel.js +1 -1
  136. package/dist/onboarding/tutorials.d.ts +3 -1
  137. package/dist/onboarding/tutorials.js +2 -1
  138. package/dist/palette/app-sources.js +1 -1
  139. package/dist/palette/headless/app-sources.js +10 -0
  140. package/dist/palette/headless/labels.js +2 -0
  141. package/dist/session/ArtifactsPanel.js +1 -1
  142. package/dist/session/PanelAttention.d.ts +14 -6
  143. package/dist/session/PanelAttention.js +35 -24
  144. package/dist/session/PlanTracker.d.ts +54 -0
  145. package/dist/session/PlanTracker.js +413 -0
  146. package/dist/session/ProjectHome.d.ts +15 -2
  147. package/dist/session/ProjectHome.js +158 -85
  148. package/dist/session/RemindersPanel.d.ts +25 -0
  149. package/dist/session/RemindersPanel.js +526 -0
  150. package/dist/session/SecretsPanel.d.ts +19 -0
  151. package/dist/session/SecretsPanel.js +241 -0
  152. package/dist/session/SessionProvider.d.ts +26 -5
  153. package/dist/session/SessionProvider.js +51 -6
  154. package/dist/session/StepStatusIcon.d.ts +24 -0
  155. package/dist/session/StepStatusIcon.js +50 -0
  156. package/dist/session/TodoList.d.ts +4 -3
  157. package/dist/session/TodoList.js +6 -5
  158. package/dist/session/headless/fixture-host.d.ts +32 -22
  159. package/dist/session/headless/fixture-host.js +86 -51
  160. package/dist/session/headless/fixture-plans.d.ts +57 -0
  161. package/dist/session/headless/fixture-plans.js +141 -0
  162. package/dist/session/headless/fixture-schedules.d.ts +49 -0
  163. package/dist/session/headless/fixture-schedules.js +133 -0
  164. package/dist/session/headless/home-layout.d.ts +10 -2
  165. package/dist/session/headless/home-layout.js +7 -2
  166. package/dist/session/headless/host.d.ts +85 -13
  167. package/dist/session/headless/index.d.ts +5 -3
  168. package/dist/session/headless/index.js +5 -3
  169. package/dist/session/headless/labels.d.ts +95 -12
  170. package/dist/session/headless/labels.js +67 -18
  171. package/dist/session/headless/plans.d.ts +53 -0
  172. package/dist/session/headless/plans.js +78 -0
  173. package/dist/session/headless/reminder-labels.d.ts +63 -0
  174. package/dist/session/headless/reminder-labels.js +84 -0
  175. package/dist/session/headless/schedules.d.ts +93 -0
  176. package/dist/session/headless/schedules.js +190 -0
  177. package/dist/session/headless/secrets.d.ts +28 -0
  178. package/dist/session/headless/secrets.js +48 -0
  179. package/dist/session/index.d.ts +7 -5
  180. package/dist/session/index.js +6 -4
  181. package/dist/session/testing/contract.d.ts +18 -5
  182. package/dist/session/testing/contract.js +351 -43
  183. package/dist/session/testing/index.d.ts +4 -2
  184. package/dist/session/testing/index.js +4 -2
  185. package/dist/settings/headless/catalog.js +17 -1
  186. package/dist/settings/headless/index.d.ts +2 -2
  187. package/dist/settings/headless/index.js +3 -3
  188. package/dist/settings/headless/labels.d.ts +0 -2
  189. package/dist/settings/headless/labels.js +0 -2
  190. package/dist/settings/headless/layout.js +7 -1
  191. package/dist/settings/headless/providers.d.ts +17 -1
  192. package/dist/settings/headless/providers.js +19 -1
  193. package/dist/settings/headless/search.d.ts +1 -1
  194. package/dist/settings/rows.d.ts +1 -1
  195. package/dist/settings/rows.js +2 -2
  196. package/dist/settings/sections/appearance/AppearanceSection.js +2 -2
  197. package/dist/settings/sections/claude-import/ClaudeImportDialog.js +1 -1
  198. package/dist/settings/sections/editor/EditorSection.js +1 -1
  199. package/dist/settings/sections/environments/EnvironmentsSection.js +1 -1
  200. package/dist/settings/sections/extensions/ChangeOriginDialog.js +1 -1
  201. package/dist/settings/sections/extensions/CreateExtensionDialog.js +1 -1
  202. package/dist/settings/sections/extensions/ExtensionsSection.js +1 -1
  203. package/dist/settings/sections/host-catalog/HostCatalogSection.js +1 -1
  204. package/dist/settings/sections/instructions/InstructionsSection.js +1 -1
  205. package/dist/settings/sections/keybindings/labels.d.ts +2 -0
  206. package/dist/settings/sections/keybindings/labels.js +2 -0
  207. package/dist/settings/sections/keybindings/rows.js +8 -0
  208. package/dist/settings/sections/mcp/McpSection.js +1 -1
  209. package/dist/settings/sections/mcp/McpServerRow.js +1 -1
  210. package/dist/settings/sections/models/ModelRows.js +2 -2
  211. package/dist/settings/sections/providers/ProvidersSection.js +209 -201
  212. package/dist/settings/sections/providers/ServerProvidersSection.js +1 -1
  213. package/dist/settings/sections/shared/catalog.js +1 -1
  214. package/dist/settings/sections/skills/SkillList.js +1 -1
  215. package/dist/settings/sections/skills/SkillsSection.js +2 -2
  216. package/dist/styles.css +59 -1
  217. package/dist/terminal/HostTerminalSurface.js +2 -2
  218. package/dist/workspace/PanelContentView.d.ts +22 -4
  219. package/dist/workspace/PanelContentView.js +112 -16
  220. package/dist/workspace/PanelGlyph.d.ts +21 -0
  221. package/dist/workspace/PanelGlyph.js +33 -0
  222. package/dist/workspace/PanelHome.js +5 -3
  223. package/dist/workspace/PanelStrip.js +11 -4
  224. package/dist/workspace/PanelToolbar.d.ts +32 -0
  225. package/dist/workspace/PanelToolbar.js +194 -0
  226. package/dist/workspace/WorkspaceProvider.d.ts +3 -1
  227. package/dist/workspace/WorkspaceProvider.js +6 -2
  228. package/dist/workspace/extension-tabs.js +5 -2
  229. package/dist/workspace/headless/host.d.ts +4 -0
  230. package/dist/workspace/headless/index.d.ts +3 -1
  231. package/dist/workspace/headless/index.js +4 -2
  232. package/dist/workspace/headless/labels.d.ts +10 -0
  233. package/dist/workspace/headless/labels.js +11 -1
  234. package/dist/workspace/headless/pages.d.ts +15 -0
  235. package/dist/workspace/headless/pages.js +49 -0
  236. package/dist/workspace/headless/tab-mark.d.ts +14 -0
  237. package/dist/workspace/headless/tab-mark.js +27 -0
  238. package/dist/workspace/headless/view.d.ts +7 -1
  239. package/dist/workspace/index.d.ts +3 -2
  240. package/dist/workspace/index.js +3 -2
  241. package/dist/workspace/testing/index.js +6 -0
  242. package/dist/workspace/workspace-key-commands.js +3 -3
  243. package/package.json +2 -2
  244. package/src/styles/motion.css +13 -0
  245. package/src/styles/onboarding.css +0 -1
  246. package/src/styles/primitives.css +10 -0
  247. package/src/styles/workspace.css +17 -0
  248. package/dist/session/TodosPanel.d.ts +0 -19
  249. package/dist/session/TodosPanel.js +0 -251
  250. package/dist/session/headless/todos.d.ts +0 -22
  251. package/dist/session/headless/todos.js +0 -38
@@ -4,6 +4,7 @@ import { BTN_GHOST_LEADING, BTN_PRIMARY, CardError, INPUT, useAutoFocus } from "
4
4
  import { QuestionField, isRequired } from "./QuestionField.js";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
6
  import { useMemo, useRef, useState } from "react";
7
+ import { isSecretAnswer } from "zidane/chat/pure";
7
8
  //#region src/chat/interactions/QuestionForm.tsx
8
9
  /**
9
10
  * `ask_user` as a card (the desktop app's inbox, `InteractionCard`). The canonical `QuestionPayload` as a form:
@@ -21,6 +22,13 @@ import { useMemo, useRef, useState } from "react";
21
22
  *
22
23
  * Two ways out: **Send** answers (`onAnswer`); **Dismiss** (`onDismiss`,
23
24
  * shown when given) cancels so the agent moves on without an answer.
25
+ *
26
+ * A `secret` question takes a password field and a TTL (`SecretInput`) and
27
+ * answers with a `SecretAnswer`, which the host saves and swaps for a
28
+ * reference before anything records it. A form with secrets says **Save
29
+ * securely** (only secrets) and offers **Decline** in place of Dismiss: it
30
+ * answers every secret with `secret-declined`. A form of secrets alone has
31
+ * no additional instructions. Nothing here persists the typed value.
24
32
  * Leaving the card alone keeps the question pending. Markdown (the intro)
25
33
  * draws through the transcript's `Markdown` slot unless `Markdown` is passed.
26
34
  */
@@ -40,21 +48,26 @@ function QuestionForm({ request, autoFocus = false, onAnswer, onDismiss, Markdow
40
48
  const [error, setError] = useState(null);
41
49
  const rootRef = useRef(null);
42
50
  useAutoFocus(rootRef, autoFocus);
51
+ const secretIds = useMemo(() => payload.questions.filter((q) => q.type === "secret").map((q) => q.id), [payload.questions]);
52
+ const onlySecrets = secretIds.length > 0 && secretIds.length === payload.questions.length;
43
53
  const canSubmit = useMemo(() => payload.questions.every((q) => {
44
- if (!isRequired(q)) return true;
45
54
  const value = answers[q.id];
55
+ if (q.type === "secret") {
56
+ const typed = isSecretAnswer(value) && value.kind === "secret-value" ? value.value : "";
57
+ return !isRequired(q) || typed.trim().length > 0;
58
+ }
59
+ if (!isRequired(q)) return true;
46
60
  if (q.type === "confirm") return typeof value === "boolean";
47
61
  if (q.type === "select" && q.multi) return Array.isArray(value) && value.length > 0;
48
62
  return typeof value === "string" && value.trim().length > 0;
49
63
  }), [answers, payload.questions]);
50
- const submit = async () => {
51
- if (busy || !canSubmit) return;
64
+ const send = async (sent) => {
52
65
  setBusy(true);
53
66
  setError(null);
54
67
  try {
55
68
  await onAnswer({
56
69
  kind: "question",
57
- answers,
70
+ answers: sent,
58
71
  ...instructions.trim() ? { instructions: instructions.trim() } : {}
59
72
  });
60
73
  } catch (err) {
@@ -62,6 +75,22 @@ function QuestionForm({ request, autoFocus = false, onAnswer, onDismiss, Markdow
62
75
  setBusy(false);
63
76
  }
64
77
  };
78
+ const submit = async () => {
79
+ if (busy || !canSubmit) return;
80
+ const sent = { ...answers };
81
+ for (const id of secretIds) {
82
+ const value = sent[id];
83
+ if (!isSecretAnswer(value) || value.kind === "secret-value" && value.value.trim() === "") delete sent[id];
84
+ }
85
+ await send(sent);
86
+ };
87
+ /** Every secret answered as declined; the other answers go as they are. */
88
+ const decline = async () => {
89
+ if (busy) return;
90
+ const sent = { ...answers };
91
+ for (const id of secretIds) sent[id] = { kind: "secret-declined" };
92
+ await send(sent);
93
+ };
65
94
  /** Explicit dismissal: the agent is told there is no answer and continues. */
66
95
  const dismiss = async () => {
67
96
  if (busy || !onDismiss) return;
@@ -100,9 +129,10 @@ function QuestionForm({ request, autoFocus = false, onAnswer, onDismiss, Markdow
100
129
  value: answers[q.id],
101
130
  onChange: (v) => setAnswer(q.id, v),
102
131
  requestId: request.id,
103
- labels
132
+ labels,
133
+ onSubmit: () => void submit()
104
134
  }, q.id)),
105
- /* @__PURE__ */ jsxs("div", {
135
+ !onlySecrets && /* @__PURE__ */ jsxs("div", {
106
136
  className: "flex flex-col gap-1.5",
107
137
  children: [/* @__PURE__ */ jsxs("div", {
108
138
  className: "flex items-baseline gap-1.5",
@@ -127,7 +157,14 @@ function QuestionForm({ request, autoFocus = false, onAnswer, onDismiss, Markdow
127
157
  /* @__PURE__ */ jsxs("div", {
128
158
  className: "flex items-center gap-2 pt-1",
129
159
  children: [
130
- onDismiss && /* @__PURE__ */ jsx("button", {
160
+ secretIds.length > 0 ? /* @__PURE__ */ jsx("button", {
161
+ type: "button",
162
+ onClick: () => void decline(),
163
+ disabled: busy,
164
+ title: labels.declineSecretHint,
165
+ className: BTN_GHOST_LEADING,
166
+ children: labels.declineSecret
167
+ }) : onDismiss && /* @__PURE__ */ jsx("button", {
131
168
  type: "button",
132
169
  onClick: () => void dismiss(),
133
170
  disabled: busy,
@@ -143,7 +180,7 @@ function QuestionForm({ request, autoFocus = false, onAnswer, onDismiss, Markdow
143
180
  disabled: busy || !canSubmit,
144
181
  className: BTN_PRIMARY,
145
182
  "data-testid": "inbox-send",
146
- children: labels.sendAnswers(payload.questions.length)
183
+ children: onlySecrets ? labels.saveSecurely : labels.sendAnswers(payload.questions.length)
147
184
  })
148
185
  ]
149
186
  })
@@ -158,7 +195,7 @@ function QuestionForm({ request, autoFocus = false, onAnswer, onDismiss, Markdow
158
195
  *
159
196
  * @param props - Component props: the `payload` that was asked, the `answers`, optional `instructions`, a unique `id`, and an optional `Markdown` renderer.
160
197
  */
161
- function AnsweredQuestions({ payload, answers, instructions, id, Markdown: MarkdownProp, className, style }) {
198
+ function AnsweredQuestions({ payload, answers, instructions, id, Markdown: MarkdownProp, onOpenSecrets, className, style }) {
162
199
  const labels = useChatLabels();
163
200
  const slots = useTranscriptRenderers();
164
201
  const Markdown = MarkdownProp ?? slots.Markdown;
@@ -177,7 +214,8 @@ function AnsweredQuestions({ payload, answers, instructions, id, Markdown: Markd
177
214
  onChange: () => void 0,
178
215
  requestId: id,
179
216
  labels,
180
- readOnly: true
217
+ readOnly: true,
218
+ onOpenSecrets
181
219
  }, q.id)),
182
220
  instructions && instructions.trim() !== "" && /* @__PURE__ */ jsxs("div", {
183
221
  className: "flex flex-col gap-1",
@@ -0,0 +1,32 @@
1
+ import { CSSProperties, Ref } from "react";
2
+ import { SecretTtl } from "zidane/chat/pure";
3
+ //#region src/chat/interactions/SecretInput.d.ts
4
+ /** Props for {@link SecretInput}. */
5
+ interface SecretInputProps {
6
+ /** Id of the password field: a `<label htmlFor>` names it. */
7
+ id: string;
8
+ /** The TTL picked. */
9
+ ttl: SecretTtl;
10
+ /** Called on every keystroke with the typed value and the picked TTL. Keep the value out of anything logged or saved. */
11
+ onChange: (value: string, ttl: SecretTtl) => void;
12
+ /** Ids of the elements that describe the field (the question's help). */
13
+ describedBy?: string;
14
+ /** Marks the field required for assistive tech. */
15
+ required?: boolean;
16
+ /** Called on Enter in the password field. */
17
+ onSubmit?: () => void;
18
+ /** Ref to the password field. */
19
+ inputRef?: Ref<HTMLInputElement>;
20
+ /** Extra classes on the root element. */
21
+ className?: string;
22
+ /** Inline styles on the root element, merged after the component's own. */
23
+ style?: CSSProperties;
24
+ }
25
+ /**
26
+ * Renders a password field, a TTL picker and the note on where the value is kept.
27
+ *
28
+ * @param props - The {@link SecretInputProps}.
29
+ */
30
+ declare function SecretInput({ id, ttl, onChange, describedBy, required, onSubmit, inputRef, className, style }: SecretInputProps): import("react").JSX.Element;
31
+ //#endregion
32
+ export { SecretInput, SecretInputProps };
@@ -0,0 +1,72 @@
1
+ import { useChatLabels } from "../useChatLabels.js";
2
+ import { FIELD, INPUT } from "./card-ui.js";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ import { useRef } from "react";
5
+ import { SECRET_TTLS } from "zidane/chat/pure";
6
+ //#region src/chat/interactions/SecretInput.tsx
7
+ /**
8
+ * The value half of a secret: a password field that never holds the value in
9
+ * the DOM (uncontrolled, no `value` attribute, no autocomplete), a TTL
10
+ * picker, and the shield note that says where the value goes and for how
11
+ * long. The `ask_user` form's secret question and the Secrets panel's
12
+ * add form both draw it.
13
+ */
14
+ /**
15
+ * Renders a password field, a TTL picker and the note on where the value is kept.
16
+ *
17
+ * @param props - The {@link SecretInputProps}.
18
+ */
19
+ function SecretInput({ id, ttl, onChange, describedBy, required = false, onSubmit, inputRef, className, style }) {
20
+ const labels = useChatLabels();
21
+ const value = useRef("");
22
+ const noteId = `${id}-note`;
23
+ return /* @__PURE__ */ jsxs("div", {
24
+ className: ["flex flex-col gap-1.5", className].filter(Boolean).join(" "),
25
+ style,
26
+ children: [/* @__PURE__ */ jsxs("div", {
27
+ className: "flex items-center gap-1.5",
28
+ children: [/* @__PURE__ */ jsx("input", {
29
+ ref: inputRef,
30
+ id,
31
+ type: "password",
32
+ autoComplete: "off",
33
+ autoCorrect: "off",
34
+ autoCapitalize: "off",
35
+ spellCheck: false,
36
+ placeholder: labels.secretValuePlaceholder,
37
+ "aria-required": required || void 0,
38
+ "aria-describedby": [describedBy, noteId].filter(Boolean).join(" "),
39
+ "data-secret-input": "",
40
+ className: `${INPUT} h-8 min-w-0 flex-1`,
41
+ onChange: (e) => {
42
+ value.current = e.target.value;
43
+ onChange(value.current, ttl);
44
+ },
45
+ onKeyDown: (e) => {
46
+ if (e.key === "Enter" && !e.metaKey && !e.ctrlKey && onSubmit) {
47
+ e.preventDefault();
48
+ onSubmit();
49
+ }
50
+ }
51
+ }), /* @__PURE__ */ jsx("select", {
52
+ "aria-label": labels.secretTtlLabel,
53
+ value: ttl,
54
+ onChange: (e) => onChange(value.current, e.target.value),
55
+ className: `${FIELD} h-8 shrink-0`,
56
+ children: SECRET_TTLS.map((option) => /* @__PURE__ */ jsx("option", {
57
+ value: option,
58
+ children: labels.secretTtlName(option)
59
+ }, option))
60
+ })]
61
+ }), /* @__PURE__ */ jsxs("span", {
62
+ id: noteId,
63
+ className: "flex items-start gap-1.5 text-zg-meta leading-4 text-[var(--zg-text-muted)] zg-pretty",
64
+ children: [/* @__PURE__ */ jsx("span", {
65
+ "aria-hidden": true,
66
+ className: "i-ph-shield-check mt-px shrink-0"
67
+ }), labels.secretNote(ttl)]
68
+ })]
69
+ });
70
+ }
71
+ //#endregion
72
+ export { SecretInput };
@@ -10,8 +10,10 @@ declare const BTN_GHOST: string;
10
10
  declare const BTN_GHOST_LEADING: string;
11
11
  /** Class names of the danger button in an interaction card: the danger fill. */
12
12
  declare const BTN_DANGER: string;
13
- /** Class names of a text field in an interaction card. */
14
- declare const INPUT = "zg-well w-full text-zg-ui px-2.5 placeholder:text-[var(--zg-text-subtle)]";
13
+ /** The well of a field in an interaction card, with no width: a select sized to its options. */
14
+ declare const FIELD = "zg-well text-zg-ui px-2.5";
15
+ /** A full-width text field of a card. */
16
+ declare const INPUT = "zg-well text-zg-ui px-2.5 w-full placeholder:text-[var(--zg-text-subtle)]";
15
17
  /** Props for {@link CardError}. */
16
18
  interface CardErrorProps {
17
19
  /** The message to show, or `null` to render nothing. */
@@ -37,4 +39,4 @@ declare function CardError({ error, className, style }: CardErrorProps): import(
37
39
  */
38
40
  declare function useAutoFocus(root: RefObject<HTMLElement | null>, when: boolean): void;
39
41
  //#endregion
40
- export { BTN, BTN_DANGER, BTN_GHOST, BTN_GHOST_LEADING, BTN_PRIMARY, CardError, CardErrorProps, INPUT, useAutoFocus };
42
+ export { BTN, BTN_DANGER, BTN_GHOST, BTN_GHOST_LEADING, BTN_PRIMARY, CardError, CardErrorProps, FIELD, INPUT, useAutoFocus };
@@ -20,8 +20,10 @@ const BTN_GHOST_LEADING = buttonClass({
20
20
  });
21
21
  /** Class names of the danger button in an interaction card: the danger fill. */
22
22
  const BTN_DANGER = buttonClass({ variant: "danger-solid" });
23
- /** Class names of a text field in an interaction card. */
24
- const INPUT = "zg-well w-full text-zg-ui px-2.5 placeholder:text-[var(--zg-text-subtle)]";
23
+ /** The well of a field in an interaction card, with no width: a select sized to its options. */
24
+ const FIELD = "zg-well text-zg-ui px-2.5";
25
+ /** A full-width text field of a card. */
26
+ const INPUT = `${FIELD} w-full placeholder:text-[var(--zg-text-subtle)]`;
25
27
  /**
26
28
  * Renders an inline error message, or nothing when there is none.
27
29
  *
@@ -60,4 +62,4 @@ function useAutoFocus(root, when) {
60
62
  }, []);
61
63
  }
62
64
  //#endregion
63
- export { BTN, BTN_DANGER, BTN_GHOST, BTN_GHOST_LEADING, BTN_PRIMARY, CardError, INPUT, useAutoFocus };
65
+ export { BTN, BTN_DANGER, BTN_GHOST, BTN_GHOST_LEADING, BTN_PRIMARY, CardError, FIELD, INPUT, useAutoFocus };
@@ -5,4 +5,5 @@ import { InteractionCard, InteractionCardProps } from "./InteractionCard.js";
5
5
  import { PlanBody, PlanBodyProps, PlanCard, PlanCardProps } from "./PlanCard.js";
6
6
  import { QuestionField, QuestionFieldProps, isRequired } from "./QuestionField.js";
7
7
  import { AnsweredQuestions, AnsweredQuestionsProps, QuestionForm, QuestionFormProps, seedDefaults } from "./QuestionForm.js";
8
- export { AnsweredQuestions, AnsweredQuestionsProps, HostInteractions, HostInteractionsProps, InboxPanel, InboxPanelProps, InteractionCard, InteractionCardProps, PlanBody, PlanBodyProps, PlanCard, PlanCardProps, QuestionField, QuestionFieldProps, QuestionForm, QuestionFormProps, isRequired, seedDefaults, useAllInteractions, useInteractionHead, usePendingInteractions };
8
+ import { SecretInput, SecretInputProps } from "./SecretInput.js";
9
+ export { AnsweredQuestions, AnsweredQuestionsProps, HostInteractions, HostInteractionsProps, InboxPanel, InboxPanelProps, InteractionCard, InteractionCardProps, PlanBody, PlanBodyProps, PlanCard, PlanCardProps, QuestionField, QuestionFieldProps, QuestionForm, QuestionFormProps, SecretInput, SecretInputProps, isRequired, seedDefaults, useAllInteractions, useInteractionHead, usePendingInteractions };
@@ -1,8 +1,9 @@
1
1
  import { useAllInteractions, useInteractionHead, usePendingInteractions } from "./hooks.js";
2
2
  import { PlanBody, PlanCard } from "./PlanCard.js";
3
+ import { SecretInput } from "./SecretInput.js";
3
4
  import { QuestionField, isRequired } from "./QuestionField.js";
4
5
  import { AnsweredQuestions, QuestionForm, seedDefaults } from "./QuestionForm.js";
5
6
  import { InteractionCard } from "./InteractionCard.js";
6
7
  import { HostInteractions } from "./HostInteractions.js";
7
8
  import { InboxPanel } from "./InboxPanel.js";
8
- export { AnsweredQuestions, HostInteractions, InboxPanel, InteractionCard, PlanBody, PlanCard, QuestionField, QuestionForm, isRequired, seedDefaults, useAllInteractions, useInteractionHead, usePendingInteractions };
9
+ export { AnsweredQuestions, HostInteractions, InboxPanel, InteractionCard, PlanBody, PlanCard, QuestionField, QuestionForm, SecretInput, isRequired, seedDefaults, useAllInteractions, useInteractionHead, usePendingInteractions };
@@ -525,6 +525,7 @@ function SessionSidebar(props) {
525
525
  isRenaming,
526
526
  archived: session.archived === true,
527
527
  favorite: session.favorite,
528
+ scheduled: Boolean(session.scheduleId),
528
529
  renameValue: isRenaming ? renameValue : "",
529
530
  menuOpen: menuForId === session.id,
530
531
  ...rowHandlers,
@@ -548,6 +549,7 @@ function SessionSidebar(props) {
548
549
  isRenaming: session.id === renamingId,
549
550
  archived: session.archived === true,
550
551
  favorite: session.favorite,
552
+ scheduled: Boolean(session.scheduleId),
551
553
  renameValue: session.id === renamingId ? renameValue : "",
552
554
  menuOpen: menuForId === session.id,
553
555
  ...rowHandlers,
@@ -20,17 +20,22 @@ interface SidebarFilterMenuProps {
20
20
  * and groupings join the menu, and the space's own grouping and sort are a choice.
21
21
  */
22
22
  query?: Pick<SidebarQueryLayer, 'space' | 'filters' | 'sorts' | 'groups'>;
23
+ /**
24
+ * Offer the Origin filter: All, Scheduled (a reminder started the session), Not scheduled. Pass it while
25
+ * reminders are on. A view that has an origin picked shows the row anyway, so it can be cleared.
26
+ */
27
+ origin?: boolean;
23
28
  /** Saves the view as a space of its own. Absent: no such row. */
24
29
  onSaveView?: () => void;
25
30
  /** Extra classes on the trigger button. */
26
31
  className?: string;
27
32
  }
28
33
  /**
29
- * The sidebar's filter axes in the kit's filter menu: view, status, project, activity, agent, sort,
34
+ * The sidebar's filter axes in the kit's filter menu: view, status, project, activity, agent, origin, sort,
30
35
  * and what extensions contribute (filters, sorts, groupings), with Save view as space.
31
36
  *
32
37
  * @param props - The {@link SidebarFilterMenuProps}.
33
38
  */
34
- declare function SidebarFilterMenu({ view, projects, onChange, hosts, agents, agentNames: agentNamesProp, query, onSaveView, className }: SidebarFilterMenuProps): import("react").JSX.Element;
39
+ declare function SidebarFilterMenu({ view, projects, onChange, hosts, agents, agentNames: agentNamesProp, query, origin, onSaveView, className }: SidebarFilterMenuProps): import("react").JSX.Element;
35
40
  //#endregion
36
41
  export { SidebarFilterMenu, SidebarFilterMenuProps };
@@ -26,6 +26,12 @@ const SORTS = [
26
26
  "recency"
27
27
  ];
28
28
  const ALL_AGENTS = "__all__";
29
+ const ALL_ORIGINS = "all";
30
+ const ORIGIN_CHOICES = [
31
+ ALL_ORIGINS,
32
+ "scheduled",
33
+ "unscheduled"
34
+ ];
29
35
  const ANY = "__any__";
30
36
  const SPACE = "@space";
31
37
  const NO_GROUPS = [];
@@ -43,12 +49,12 @@ function withExtension(view, change) {
43
49
  return out;
44
50
  }
45
51
  /**
46
- * The sidebar's filter axes in the kit's filter menu: view, status, project, activity, agent, sort,
52
+ * The sidebar's filter axes in the kit's filter menu: view, status, project, activity, agent, origin, sort,
47
53
  * and what extensions contribute (filters, sorts, groupings), with Save view as space.
48
54
  *
49
55
  * @param props - The {@link SidebarFilterMenuProps}.
50
56
  */
51
- function SidebarFilterMenu({ view, projects, onChange, hosts = false, agents, agentNames: agentNamesProp, query, onSaveView, className }) {
57
+ function SidebarFilterMenu({ view, projects, onChange, hosts = false, agents, agentNames: agentNamesProp, query, origin = false, onSaveView, className }) {
52
58
  const labels = useChatLabels();
53
59
  const catalogNames = useAgentNames();
54
60
  const agentNames = agentNamesProp ?? catalogNames;
@@ -209,6 +215,23 @@ function SidebarFilterMenu({ view, projects, onChange, hosts = false, agents, ag
209
215
  onChange: (next) => onChange({ agent: next === ALL_AGENTS ? null : next })
210
216
  });
211
217
  }
218
+ if (origin || view.origin) {
219
+ const current = view.origin ?? ALL_ORIGINS;
220
+ out.push({
221
+ kind: "choice",
222
+ id: "origin",
223
+ label: labels.filterOrigin,
224
+ placement: "filter",
225
+ value: labels.filterOrigins[current],
226
+ atDefault: !view.origin,
227
+ options: ORIGIN_CHOICES.map((id) => ({
228
+ id,
229
+ label: labels.filterOrigins[id]
230
+ })),
231
+ current,
232
+ onChange: (next) => onChange({ origin: next === ALL_ORIGINS ? null : next })
233
+ });
234
+ }
212
235
  return out;
213
236
  }, [
214
237
  view,
@@ -222,6 +245,7 @@ function SidebarFilterMenu({ view, projects, onChange, hosts = false, agents, ag
222
245
  query,
223
246
  agents,
224
247
  agentNames,
248
+ origin,
225
249
  labels,
226
250
  onChange
227
251
  ]);
@@ -60,6 +60,8 @@ interface SidebarSessionRowProps extends SidebarRowHandlers {
60
60
  archived: boolean;
61
61
  /** Starred. */
62
62
  favorite?: boolean;
63
+ /** A reminder started it (zidane's `scheduleId`): a clock mark beside the title. */
64
+ scheduled?: boolean;
63
65
  /** The rename field's text. */
64
66
  renameValue: string;
65
67
  /** Its menu is the open one. */
@@ -90,6 +92,6 @@ interface SidebarSessionRowProps extends SidebarRowHandlers {
90
92
  style?: CSSProperties;
91
93
  }
92
94
  /** Renders one session of the sidebar list. Memoized: keep every prop stable. */
93
- declare const SidebarSessionRow: import("react").MemoExoticComponent<({ sessionId, title, cwd, hostId, hostBadge, spaceId, isMain, isActive, isRenaming, archived, favorite, renameValue, menuOpen, onSelect, onRenameValueChange, onRenameCommit, onRenameCancel, onStartRename, onDelete, onSetArchived, onSetFavorite, onRetryEnvironment, onRunEnvironmentAction, onMoveToSpace, onMoveSession, onOpenMenu, onCloseMenu, excerpt, excerptQuery, project, updatedAt, environment, runDetails, artifactBadges, spaces, live, decoration, className, style }: SidebarSessionRowProps) => import("react").JSX.Element>;
95
+ declare const SidebarSessionRow: import("react").MemoExoticComponent<({ sessionId, title, cwd, hostId, hostBadge, spaceId, isMain, isActive, isRenaming, archived, favorite, scheduled, renameValue, menuOpen, onSelect, onRenameValueChange, onRenameCommit, onRenameCancel, onStartRename, onDelete, onSetArchived, onSetFavorite, onRetryEnvironment, onRunEnvironmentAction, onMoveToSpace, onMoveSession, onOpenMenu, onCloseMenu, excerpt, excerptQuery, project, updatedAt, environment, runDetails, artifactBadges, spaces, live, decoration, className, style }: SidebarSessionRowProps) => import("react").JSX.Element>;
94
96
  //#endregion
95
97
  export { SidebarRowHandlers, SidebarSessionRow, SidebarSessionRowProps };
@@ -32,7 +32,7 @@ const ExcerptHighlight = memo(({ text, query }) => {
32
32
  });
33
33
  ExcerptHighlight.displayName = "ExcerptHighlight";
34
34
  /** Renders one session of the sidebar list. Memoized: keep every prop stable. */
35
- const SidebarSessionRow = memo(({ sessionId, title, cwd, hostId, hostBadge = true, spaceId, isMain, isActive, isRenaming, archived, favorite = false, renameValue, menuOpen, onSelect, onRenameValueChange, onRenameCommit, onRenameCancel, onStartRename, onDelete, onSetArchived, onSetFavorite, onRetryEnvironment, onRunEnvironmentAction, onMoveToSpace, onMoveSession, onOpenMenu, onCloseMenu, excerpt, excerptQuery, project, updatedAt, environment, runDetails, artifactBadges, spaces, live, decoration, className, style }) => {
35
+ const SidebarSessionRow = memo(({ sessionId, title, cwd, hostId, hostBadge = true, spaceId, isMain, isActive, isRenaming, archived, favorite = false, scheduled = false, renameValue, menuOpen, onSelect, onRenameValueChange, onRenameCommit, onRenameCancel, onStartRename, onDelete, onSetArchived, onSetFavorite, onRetryEnvironment, onRunEnvironmentAction, onMoveToSpace, onMoveSession, onOpenMenu, onCloseMenu, excerpt, excerptQuery, project, updatedAt, environment, runDetails, artifactBadges, spaces, live, decoration, className, style }) => {
36
36
  const { SessionStatusDot, RowMeta, RowArtifacts } = live;
37
37
  const host = useSidebarHost();
38
38
  const labels = useSidebarLabels();
@@ -106,10 +106,15 @@ const SidebarSessionRow = memo(({ sessionId, title, cwd, hostId, hostBadge = tru
106
106
  surface: "title",
107
107
  links: false
108
108
  }) : void 0,
109
- ...decoration && (decoration.icon || decoration.chips.length > 0 || decoration.component) ? { badges: /* @__PURE__ */ jsx(SidebarDecoration, {
109
+ ...scheduled || decoration && (decoration.icon || decoration.chips.length > 0 || decoration.component) ? { badges: /* @__PURE__ */ jsxs(Fragment, { children: [scheduled && /* @__PURE__ */ jsx("span", {
110
+ role: "img",
111
+ "aria-label": labels.rowScheduled,
112
+ title: labels.rowScheduled,
113
+ className: "i-ph-clock shrink-0 text-zg-label text-[var(--zg-text-muted)]"
114
+ }), decoration && /* @__PURE__ */ jsx(SidebarDecoration, {
110
115
  decoration,
111
116
  sessionId
112
- }) } : {},
117
+ })] }) } : {},
113
118
  meta: typeof updatedAt === "number" ? /* @__PURE__ */ jsx(RowMeta, {
114
119
  sessionId,
115
120
  updatedAt,
@@ -20,7 +20,7 @@ import { useSessionActivity } from "./useSessionActivity.js";
20
20
  import { useSessionBadges } from "./useSessionBadges.js";
21
21
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
22
22
  import { memo, useCallback, useEffect, useMemo, useReducer, useState } from "react";
23
- import { sessionBadgeTarget } from "zidane/chat/pure";
23
+ import { isRunEstimated, sessionBadgeTarget } from "zidane/chat/pure";
24
24
  //#region src/chat/sidebar/sidebar-live.tsx
25
25
  /**
26
26
  * What a sidebar row says about its session beyond the title, from the
@@ -319,10 +319,14 @@ function createSidebarLive(options) {
319
319
  function useSessionEstimate(sessionId) {
320
320
  return useRunEstimate(estimatesStore ? sessionId : void 0, void 0, estimatesStore);
321
321
  }
322
- /** The run's time: what it has left while the host estimated it, else how long it has gone. */
322
+ /**
323
+ * The run's time: what it has left while the host estimated it, else how long it has gone (with a mark
324
+ * saying why, when the host could not estimate it).
325
+ */
323
326
  function RunTime({ sessionId }) {
324
327
  const estimate = useSessionEstimate(sessionId);
325
- return estimate ? /* @__PURE__ */ jsx(EstimateChip, { estimate }) : /* @__PURE__ */ jsx(Elapsed, { sessionId });
328
+ if (estimate && isRunEstimated(estimate)) return /* @__PURE__ */ jsx(EstimateChip, { estimate });
329
+ return /* @__PURE__ */ jsxs(Fragment, { children: [estimate && /* @__PURE__ */ jsx(RunEstimateChip, { estimate }), /* @__PURE__ */ jsx(Elapsed, { sessionId })] });
326
330
  }
327
331
  /**
328
332
  * The estimate chip. Its tooltip says how long the run has gone, read from the run's start when the
@@ -352,7 +356,7 @@ function createSidebarLive(options) {
352
356
  className: "self-center w-1.5 h-1.5 rounded-full bg-[var(--zg-accent)]"
353
357
  }),
354
358
  labels.rowWorking,
355
- estimate && /* @__PURE__ */ jsx(EstimateChip, { estimate })
359
+ estimate && (isRunEstimated(estimate) ? /* @__PURE__ */ jsx(EstimateChip, { estimate }) : /* @__PURE__ */ jsx(RunEstimateChip, { estimate }))
356
360
  ]
357
361
  }) : /* @__PURE__ */ jsx(Ago, {
358
362
  at: updatedAt,
@@ -0,0 +1,34 @@
1
+ import { RunFailure } from "../headless/transcript/run-failures.js";
2
+ import "../headless/transcript/index.js";
3
+ import { CSSProperties } from "react";
4
+ import { AuthFailure } from "zidane/chat/pure";
5
+ import { StreamEvent } from "zidane/chat";
6
+ //#region src/chat/transcript/AuthFailureCard.d.ts
7
+ /** Props for {@link AuthFailureCard}. */
8
+ interface AuthFailureCardProps {
9
+ /** The sign-in that failed (`detail.auth`). */
10
+ auth: AuthFailure;
11
+ /** The run's stop reason, shown muted under the headline. */
12
+ text: string;
13
+ /** The error's structured detail: the provider's own words, for the tooltip and Copy details. */
14
+ detail?: StreamEvent['detail'];
15
+ /** How the run ended and how it would resume. */
16
+ failure: RunFailure;
17
+ /** The card is the transcript's last word, with no run in progress: it offers its actions. */
18
+ resumable: boolean;
19
+ /** Called with the prompt that resumes the run (Retry, and after a sign-in or a switch). Absent: no Retry. */
20
+ onResume?: (prompt: string) => void;
21
+ /** Extra classes on the root element. */
22
+ className?: string;
23
+ /** Inline styles on the root element, merged after the component's own. */
24
+ style?: CSSProperties;
25
+ }
26
+ /**
27
+ * Renders a sign-in failure as a card with its fixes; see the module
28
+ * comment for the rules.
29
+ *
30
+ * @param props - Component props.
31
+ */
32
+ declare const AuthFailureCard: import("react").MemoExoticComponent<({ auth, text, detail, failure, resumable, onResume, className, style }: AuthFailureCardProps) => import("react").JSX.Element>;
33
+ //#endregion
34
+ export { AuthFailureCard, AuthFailureCardProps };