@mcp-b/react-components 0.46.7 → 0.48.0

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 (130) hide show
  1. package/dist/{CodeBlock-CcteqDvA.js → CodeBlock-BSJl682D.js} +1 -1
  2. package/dist/Correspondent-7K6uNLUm.d.ts +64 -0
  3. package/dist/{FileTree-jtP9471I.js → FileTree-DvE0hNZu.js} +1 -1
  4. package/dist/{SetupChecklist-BXwSSorj.js → SetupChecklist-DeTU9YpW.js} +1 -1
  5. package/dist/ThinkChat-CwMdEum8.d.ts +185 -0
  6. package/dist/{ThinkChat-qztQ6Clo.js → ThinkChat-DiI6hhDP.js} +14 -14
  7. package/dist/ThinkThreadPicker-yFz4vvIf.d.ts +91 -0
  8. package/dist/{Workspace-DZusrEeP.d.ts → Workspace-LIoU30n7.d.ts} +13 -2
  9. package/dist/{WorkspaceFileView-D0HyoUV8.js → WorkspaceFileView-C_WnYm-a.js} +4 -4
  10. package/dist/{WorkspaceLink-DtH66bAY.js → WorkspaceLink-B1d2GIGl.js} +7 -2
  11. package/dist/WorkspaceLive-DfjH1Ypm.d.ts +61 -0
  12. package/dist/{WorkspaceMessageResponse-CJCmGvTx.js → WorkspaceMessageResponse-BqOezptB.js} +79 -40
  13. package/dist/WorkspaceMessageResponse-kJYU8Onj.d.ts +48 -0
  14. package/dist/components/agents-sdk/AgentActivity.js +1 -1
  15. package/dist/components/agents-sdk/AgentChat.js +2 -2
  16. package/dist/components/agents-sdk/BrowserLiveScreen.js +1 -1
  17. package/dist/components/agents-sdk/BrowserLiveView.js +1 -1
  18. package/dist/components/agents-sdk/BrowserReplay.js +1 -1
  19. package/dist/components/agents-sdk/BrowserRunPanel.js +1 -1
  20. package/dist/components/agents-sdk/ManagerOffice.d.ts +41 -50
  21. package/dist/components/agents-sdk/ManagerOffice.js +359 -978
  22. package/dist/components/agents-sdk/McpConnectionRequest.js +1 -1
  23. package/dist/components/agents-sdk/McpPluginCatalog.js +1 -1
  24. package/dist/components/agents-sdk/McpServerPicker.js +1 -1
  25. package/dist/components/agents-sdk/ModelSelector.js +1 -1
  26. package/dist/components/agents-sdk/PromptInputCommands.js +1 -1
  27. package/dist/components/agents-sdk/SubagentRunIndicator.js +1 -1
  28. package/dist/components/agents-sdk/ThinkChat.d.ts +1 -180
  29. package/dist/components/agents-sdk/ThinkChat.js +1 -1
  30. package/dist/components/agents-sdk/ThinkChatToolPanels.js +1 -1
  31. package/dist/components/agents-sdk/ThinkExecutionDetail.js +1 -1
  32. package/dist/components/agents-sdk/ThinkExecutionStatus.js +1 -1
  33. package/dist/components/agents-sdk/ThinkExecutionWorkbench.js +1 -1
  34. package/dist/components/agents-sdk/ThinkFullApp.d.ts +12 -3
  35. package/dist/components/agents-sdk/ThinkFullApp.js +15 -3
  36. package/dist/components/agents-sdk/ThinkRoutineBrowser.js +1 -1
  37. package/dist/components/agents-sdk/ThinkRoutineForm.js +1 -1
  38. package/dist/components/agents-sdk/ThinkRoutineLibrary.js +1 -1
  39. package/dist/components/agents-sdk/ThinkSidepanel.d.ts +20 -5
  40. package/dist/components/agents-sdk/ThinkSidepanel.js +48 -36
  41. package/dist/components/agents-sdk/ThinkThreadPicker.d.ts +1 -90
  42. package/dist/components/agents-sdk/ThinkThreadPicker.js +1 -1
  43. package/dist/components/agents-sdk/Workspace.d.ts +2 -2
  44. package/dist/components/agents-sdk/Workspace.js +13 -10
  45. package/dist/components/agents-sdk/WorkspaceBrowser.d.ts +1 -1
  46. package/dist/components/agents-sdk/WorkspaceBrowser.js +1 -1
  47. package/dist/components/agents-sdk/WorkspaceConcept.d.ts +45 -0
  48. package/dist/components/agents-sdk/WorkspaceConcept.js +42 -0
  49. package/dist/components/agents-sdk/WorkspaceCorrespondence.d.ts +96 -0
  50. package/dist/components/agents-sdk/WorkspaceCorrespondence.js +429 -0
  51. package/dist/components/agents-sdk/WorkspaceExecution.d.ts +115 -0
  52. package/dist/components/agents-sdk/WorkspaceExecution.js +330 -0
  53. package/dist/components/agents-sdk/WorkspaceExplorer.d.ts +1 -1
  54. package/dist/components/agents-sdk/WorkspaceExplorer.js +2 -2
  55. package/dist/components/agents-sdk/WorkspaceFileView.js +1 -1
  56. package/dist/components/agents-sdk/WorkspaceHeader.js +1 -1
  57. package/dist/components/agents-sdk/WorkspaceLink.js +1 -1
  58. package/dist/components/agents-sdk/WorkspaceLive.d.ts +2 -0
  59. package/dist/components/agents-sdk/WorkspaceLive.js +113 -0
  60. package/dist/components/agents-sdk/WorkspaceMessageResponse.d.ts +2 -2
  61. package/dist/components/agents-sdk/WorkspaceMessageResponse.js +2 -2
  62. package/dist/components/agents-sdk/WorkspaceMountManager.js +1 -1
  63. package/dist/components/agents-sdk/WorkspaceProject.d.ts +131 -0
  64. package/dist/components/agents-sdk/WorkspaceProject.js +238 -0
  65. package/dist/components/agents-sdk/WorkspaceUserScript.d.ts +47 -0
  66. package/dist/components/agents-sdk/WorkspaceUserScript.js +146 -0
  67. package/dist/components/ai-sdk/Activity.js +1 -1
  68. package/dist/components/ai-sdk/AgentChatStartScreen.js +1 -1
  69. package/dist/components/ai-sdk/Approval.js +1 -1
  70. package/dist/components/ai-sdk/Artifact.js +3 -3
  71. package/dist/components/ai-sdk/ChainOfThought.d.ts +1 -1
  72. package/dist/components/ai-sdk/ChainOfThought.js +1 -1
  73. package/dist/components/ai-sdk/Checkpoint.js +1 -1
  74. package/dist/components/ai-sdk/CodeBlock.js +1 -1
  75. package/dist/components/ai-sdk/ComposerLink.d.ts +4 -1
  76. package/dist/components/ai-sdk/ComposerLink.js +4 -3
  77. package/dist/components/ai-sdk/ConnectedAppCards.d.ts +29 -2
  78. package/dist/components/ai-sdk/ConnectedAppCards.js +78 -103
  79. package/dist/components/ai-sdk/Conversation.js +1 -1
  80. package/dist/components/ai-sdk/Correspondent.d.ts +2 -0
  81. package/dist/components/ai-sdk/Correspondent.js +145 -0
  82. package/dist/components/ai-sdk/Goal.js +1 -1
  83. package/dist/components/ai-sdk/MediaPreviewCard.js +1 -1
  84. package/dist/components/ai-sdk/Message.js +1 -1
  85. package/dist/components/ai-sdk/MessageScroller.js +1 -1
  86. package/dist/components/ai-sdk/MessageScrollerVirtual.js +1 -1
  87. package/dist/components/ai-sdk/Plan.js +1 -1
  88. package/dist/components/ai-sdk/PromptInput.js +1 -1
  89. package/dist/components/ai-sdk/Queue.js +1 -1
  90. package/dist/components/ai-sdk/Reasoning.js +1 -1
  91. package/dist/components/ai-sdk/Sources.js +1 -1
  92. package/dist/components/ai-sdk/Task.js +1 -1
  93. package/dist/components/extension/ChatGptSignInScreen.js +1 -1
  94. package/dist/components/extension/CodexModelSelector.js +1 -1
  95. package/dist/components/extension/ConversationTabPicker.js +1 -1
  96. package/dist/components/foundations/Checkbox.js +1 -1
  97. package/dist/components/foundations/ContextMenu.js +1 -1
  98. package/dist/components/foundations/Menubar.js +1 -1
  99. package/dist/components/foundations/SearchField.js +1 -1
  100. package/dist/components/foundations/Select.js +1 -1
  101. package/dist/components/foundations/Stepper.js +1 -1
  102. package/dist/components/foundations/Toast.js +1 -1
  103. package/dist/components/foundations/icons.d.ts +2 -2
  104. package/dist/components/foundations/icons.js +2 -2
  105. package/dist/components/general-purpose/Commit.js +2 -2
  106. package/dist/components/general-purpose/EnvironmentVariables.js +2 -2
  107. package/dist/components/general-purpose/FileTree.js +1 -1
  108. package/dist/components/general-purpose/PricingPlanCard.js +1 -1
  109. package/dist/components/general-purpose/ResponsiveSidebarShell.js +1 -1
  110. package/dist/components/general-purpose/SetupChecklist.js +1 -1
  111. package/dist/components/general-purpose/Terminal.js +2 -2
  112. package/dist/components/general-purpose/TestResults.js +1 -1
  113. package/dist/components/general-purpose/ThemeModeControl.js +1 -1
  114. package/dist/components/general-purpose/WebPreview.js +1 -1
  115. package/dist/components/nanites/AgentConnection.js +2 -2
  116. package/dist/components/nanites/AgentToolDetail.d.ts +1 -1
  117. package/dist/components/nanites/AgentToolDetail.js +2 -2
  118. package/dist/{copy-button-BABPlsc-.js → copy-button-Dk2vRe9j.js} +1 -1
  119. package/dist/{icons-ChPpNMmU.d.ts → icons-CCZGYUwU.d.ts} +6 -1
  120. package/dist/{icons-BC4HZqSK.js → icons-CeGfXO21.js} +3 -2
  121. package/dist/styles/base.css +2 -2
  122. package/dist/styles/connected-app-card.css +8 -0
  123. package/dist/styles/correspondent.css +73 -0
  124. package/dist/styles/description-list.css +3 -1
  125. package/dist/styles/index.css +2 -0
  126. package/dist/styles/manager-office.css +380 -1086
  127. package/dist/styles/workspace-concepts.css +28 -0
  128. package/dist/workspace-assets-GqsCYxqT.js +168 -0
  129. package/package.json +2 -2
  130. package/dist/WorkspaceMessageResponse-D66ty4FO.d.ts +0 -24
@@ -0,0 +1,429 @@
1
+ import { t as cx } from "../../class-names-BiMDVpUo.js";
2
+ import { S as FileIcon, d as CheckIcon } from "../../icons-CeGfXO21.js";
3
+ import { Button } from "../foundations/Button.js";
4
+ import { Field } from "../foundations/Field.js";
5
+ import { Textarea } from "../foundations/Textarea.js";
6
+ import { IconButton } from "../foundations/IconButton.js";
7
+ import { a as formatErrorMessage } from "../../format-COCyV98Z.js";
8
+ import { Card, CardAction, CardContent, CardFooter, CardHeader, CardTitle } from "../foundations/Card.js";
9
+ import { DescriptionList } from "../foundations/DescriptionList.js";
10
+ import { Input } from "../foundations/Input.js";
11
+ import { EmailMessageCard, SlackMessageCard } from "../ai-sdk/ConnectedAppCards.js";
12
+ import { i as WorkspaceDeleteControl, r as httpUrl, t as FaviconMark } from "../../workspace-assets-GqsCYxqT.js";
13
+ import * as React from "react";
14
+ import { createElement } from "react";
15
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
16
+ import { hashKey, useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
17
+ //#region src/components/agents-sdk/WorkspaceCorrespondence.tsx
18
+ const SAVE_DEBOUNCE_MS = 400;
19
+ const SEND_BLOCKED_MESSAGE = "Your edit has not saved, so nothing was sent. Retry the save first.";
20
+ const FILE_MISSING_MESSAGE = "The file is no longer in the workspace.";
21
+ const SAVE_UNAVAILABLE_MESSAGE = "Saving is no longer available.";
22
+ const SEND_UNAVAILABLE_MESSAGE = "Sending is no longer available.";
23
+ function fieldValue(fields, name) {
24
+ return fields.find((field) => field.name === name)?.value;
25
+ }
26
+ function replaceFields(fields, values) {
27
+ const remaining = new Map(Object.entries(values));
28
+ const next = fields.map((field) => {
29
+ if (!remaining.has(field.name)) return field;
30
+ const value = remaining.get(field.name) ?? "";
31
+ remaining.delete(field.name);
32
+ return {
33
+ ...field,
34
+ value
35
+ };
36
+ });
37
+ for (const [name, value] of remaining) {
38
+ if (value === void 0 || value === "") continue;
39
+ next.push({
40
+ name,
41
+ label: name.replace(/[-_]+/gu, " ").replace(/\b\w/gu, (letter) => letter.toUpperCase()),
42
+ value
43
+ });
44
+ }
45
+ return next;
46
+ }
47
+ function displayKind(kind) {
48
+ return kind.trim().split(/[-_\s]+/u).filter(Boolean).map((word) => word[0].toUpperCase() + word.slice(1)).join(" ");
49
+ }
50
+ /**
51
+ * File-level header controls shared by every channel presentation, so the rich
52
+ * email and Slack cards carry the same Open and Delete affordances the generic
53
+ * card has instead of dropping them.
54
+ */
55
+ function CorrespondenceHeaderActions({ kind, path, onDelete, onOpen }) {
56
+ return /* @__PURE__ */ jsxs(Fragment, { children: [onOpen ? /* @__PURE__ */ jsx(IconButton, {
57
+ label: `Open ${kind}`,
58
+ tooltip: path,
59
+ variant: "ghost",
60
+ color: "neutral",
61
+ onClick: onOpen,
62
+ children: /* @__PURE__ */ jsx(FileIcon, {})
63
+ }) : null, onDelete ? /* @__PURE__ */ jsx(WorkspaceDeleteControl, {
64
+ name: `${kind} draft`,
65
+ onDelete
66
+ }) : null] });
67
+ }
68
+ /**
69
+ * Generic reviewed outbound message used after the public component has
70
+ * selected richer channel-specific presentation where one exists.
71
+ */
72
+ function GenericWorkspaceCorrespondenceCard({ className, body, fields, kind, path, icon, saveState, state = "draft", onChange, onDelete, onOpen, onSend, ref, ...props }) {
73
+ const titleId = React.useId();
74
+ const fieldId = React.useId();
75
+ const editing = onChange != null;
76
+ const [busy, setBusy] = React.useState(false);
77
+ const [errorMessage, setErrorMessage] = React.useState("");
78
+ const draft = {
79
+ fields,
80
+ body
81
+ };
82
+ const ariaLabel = props["aria-label"];
83
+ const ariaLabelledBy = props["aria-labelledby"] ?? (ariaLabel ? void 0 : titleId);
84
+ const saveBlocked = saveState !== void 0;
85
+ const saveErrorMessage = saveState?.status === "error" ? saveState.message : "";
86
+ const send = async () => {
87
+ if (!onSend || busy) return;
88
+ setBusy(true);
89
+ setErrorMessage("");
90
+ try {
91
+ await onSend();
92
+ } catch (error) {
93
+ setErrorMessage(error instanceof Error && error.message.trim() ? error.message : "The action could not be completed. Try again.");
94
+ } finally {
95
+ setBusy(false);
96
+ }
97
+ };
98
+ return /* @__PURE__ */ jsxs(Card, {
99
+ ...props,
100
+ ref,
101
+ role: props.role ?? "article",
102
+ "aria-labelledby": ariaLabelledBy,
103
+ "data-slot": "workspace-correspondence-card",
104
+ "data-state": state,
105
+ size: "sm",
106
+ className: cx("connected-app-card", className),
107
+ children: [
108
+ /* @__PURE__ */ jsxs(CardHeader, { children: [/* @__PURE__ */ jsxs(CardTitle, {
109
+ id: titleId,
110
+ className: "connected-app-card__title",
111
+ render: /* @__PURE__ */ jsx("h3", {}),
112
+ children: [/* @__PURE__ */ jsx("span", {
113
+ className: "connected-app-card__icon",
114
+ "aria-hidden": "true",
115
+ children: icon ?? /* @__PURE__ */ jsx(FileIcon, {})
116
+ }), displayKind(kind)]
117
+ }), state === "sent" || onOpen || onDelete ? /* @__PURE__ */ jsxs(CardAction, {
118
+ className: "sigvelo-cluster",
119
+ children: [state === "sent" ? /* @__PURE__ */ jsxs("span", {
120
+ className: "connected-app-card__status",
121
+ "data-state": "sent",
122
+ children: [/* @__PURE__ */ jsx(CheckIcon, { size: 14 }), "Sent"]
123
+ }) : null, /* @__PURE__ */ jsx(CorrespondenceHeaderActions, {
124
+ kind,
125
+ path,
126
+ onDelete,
127
+ onOpen
128
+ })]
129
+ }) : null] }),
130
+ /* @__PURE__ */ jsxs(CardContent, { children: [
131
+ fields.length > 0 ? /* @__PURE__ */ jsx(DescriptionList.Root, {
132
+ align: "start",
133
+ variant: "divided",
134
+ children: fields.map((field) => {
135
+ const inputId = `${fieldId}-${field.name}`;
136
+ const href = httpUrl(field.value);
137
+ return /* @__PURE__ */ jsxs(DescriptionList.Item, { children: [/* @__PURE__ */ jsxs(DescriptionList.Term, { children: [href ? /* @__PURE__ */ jsx(FaviconMark, { href }) : null, editing ? /* @__PURE__ */ jsx("label", {
138
+ htmlFor: inputId,
139
+ children: field.label
140
+ }) : field.label] }), /* @__PURE__ */ jsx(DescriptionList.Details, { children: editing ? /* @__PURE__ */ jsx(Input, {
141
+ id: inputId,
142
+ name: field.name,
143
+ type: href ? "url" : void 0,
144
+ value: field.value,
145
+ autoComplete: "off",
146
+ onChange: (event) => onChange({
147
+ ...draft,
148
+ fields: fields.map((item) => item.name === field.name ? {
149
+ ...item,
150
+ value: event.currentTarget.value
151
+ } : item)
152
+ })
153
+ }) : field.value })] }, field.name);
154
+ })
155
+ }) : null,
156
+ editing ? /* @__PURE__ */ jsxs(Field.Root, { children: [/* @__PURE__ */ jsx(Field.Label, { children: "Message" }), /* @__PURE__ */ jsx(Field.Control, {
157
+ render: /* @__PURE__ */ jsx(Textarea, {
158
+ name: "body",
159
+ rows: 4,
160
+ resize: "vertical",
161
+ autoComplete: "off"
162
+ }),
163
+ value: body,
164
+ onChange: (event) => onChange({
165
+ ...draft,
166
+ body: event.currentTarget.value
167
+ })
168
+ })] }) : body ? /* @__PURE__ */ jsx("p", {
169
+ className: "connected-app-card__body",
170
+ children: body
171
+ }) : null,
172
+ saveErrorMessage ? /* @__PURE__ */ jsxs("div", {
173
+ className: "connected-app-card__save-error",
174
+ children: [/* @__PURE__ */ jsx(Field.Errors, { errors: [saveErrorMessage] }), saveState?.status === "error" && saveState.onRetry ? /* @__PURE__ */ jsx(Button, {
175
+ type: "button",
176
+ size: "sm",
177
+ variant: "ghost",
178
+ color: "neutral",
179
+ onClick: saveState.onRetry,
180
+ children: "Retry save"
181
+ }) : null]
182
+ }) : null,
183
+ errorMessage ? /* @__PURE__ */ jsx(Field.Errors, { errors: [errorMessage] }) : null,
184
+ /* @__PURE__ */ jsx("span", {
185
+ className: "sigvelo-visually-hidden",
186
+ role: "status",
187
+ "aria-atomic": "true",
188
+ children: saveErrorMessage || errorMessage || (saveState?.status === "saving" ? "Saving" : busy ? "Submitting" : "")
189
+ })
190
+ ] }),
191
+ onSend ? /* @__PURE__ */ jsx(CardFooter, {
192
+ className: "connected-app-card__footer",
193
+ children: /* @__PURE__ */ jsx(Button, {
194
+ type: "button",
195
+ size: "sm",
196
+ disabled: busy || saveBlocked,
197
+ onClick: () => void send(),
198
+ children: "Send"
199
+ })
200
+ }) : null
201
+ ]
202
+ });
203
+ }
204
+ /**
205
+ * Reviewed workspace correspondence. The host passes one normalized file
206
+ * shape; this component owns channel-specific presentation, the sent
207
+ * snapshot, and falls back to the generic card for kinds without a richer
208
+ * design-system surface.
209
+ */
210
+ function WorkspaceCorrespondenceCard({ body, fields, kind, path, icon, saveState, state = "draft", onChange, onDelete, onOpen, onSend, ref, ...props }) {
211
+ const normalizedKind = kind.trim().toLowerCase();
212
+ const settled = state === "sent";
213
+ const change = settled ? void 0 : onChange;
214
+ const send = settled ? void 0 : onSend;
215
+ const headerActions = /* @__PURE__ */ jsx(CorrespondenceHeaderActions, {
216
+ kind,
217
+ path,
218
+ onDelete,
219
+ onOpen
220
+ });
221
+ if (normalizedKind === "email") {
222
+ const draft = {
223
+ from: fieldValue(fields, "from"),
224
+ to: fieldValue(fields, "to"),
225
+ subject: fieldValue(fields, "subject") ?? "",
226
+ body
227
+ };
228
+ return /* @__PURE__ */ jsx(EmailMessageCard, {
229
+ ...props,
230
+ ...draft,
231
+ ref,
232
+ icon,
233
+ headerActions,
234
+ state: settled ? "sent" : "pending",
235
+ saveState: settled ? void 0 : saveState,
236
+ onChange: change ? (next) => {
237
+ change({
238
+ fields: replaceFields(fields, {
239
+ from: next.from,
240
+ to: next.to,
241
+ subject: next.subject
242
+ }),
243
+ body: next.body ?? ""
244
+ });
245
+ } : void 0,
246
+ onSend: send
247
+ });
248
+ }
249
+ if (normalizedKind === "slack") {
250
+ const draft = {
251
+ workspace: fieldValue(fields, "workspace"),
252
+ to: fieldValue(fields, "to") ?? "",
253
+ thread: fieldValue(fields, "thread"),
254
+ message: body
255
+ };
256
+ return /* @__PURE__ */ jsx(SlackMessageCard, {
257
+ ...props,
258
+ ...draft,
259
+ ref,
260
+ icon,
261
+ headerActions,
262
+ state: settled ? "sent" : "pending",
263
+ saveState: settled ? void 0 : saveState,
264
+ onChange: change ? (next) => {
265
+ change({
266
+ fields: replaceFields(fields, {
267
+ workspace: next.workspace,
268
+ to: next.to,
269
+ thread: next.thread
270
+ }),
271
+ body: next.message
272
+ });
273
+ } : void 0,
274
+ onSend: send
275
+ });
276
+ }
277
+ return /* @__PURE__ */ jsx(GenericWorkspaceCorrespondenceCard, {
278
+ ...props,
279
+ ref,
280
+ body,
281
+ fields,
282
+ kind,
283
+ path,
284
+ icon,
285
+ state,
286
+ saveState: settled ? void 0 : saveState,
287
+ onChange: change,
288
+ onDelete,
289
+ onOpen,
290
+ onSend: send
291
+ });
292
+ }
293
+ /**
294
+ * Query-backed reviewed correspondence. The host supplies normalized reads
295
+ * and writes; this adapter owns the draft, its debounced save lifecycle, the
296
+ * save-gated Send, and the session sent latch.
297
+ *
298
+ * The visible draft is interaction state layered over query data, so an
299
+ * observer-driven refetch can never clobber typing, and a failed save is
300
+ * shown with a retry affordance instead of rendering as success. Send always
301
+ * flushes the outstanding edit first and refuses when that save fails — the
302
+ * agent must never be told to send content the workspace does not hold.
303
+ *
304
+ * Interaction state belongs to one query identity. The keyed session makes a
305
+ * source swap a real unmount, so an old save or send cannot settle onto the
306
+ * next file.
307
+ */
308
+ function WorkspaceCorrespondenceFile(props) {
309
+ return /* @__PURE__ */ createElement(WorkspaceCorrespondenceFileSession, {
310
+ ...props,
311
+ key: hashKey(props.source.queryOptions.queryKey)
312
+ });
313
+ }
314
+ function WorkspaceCorrespondenceFileSession({ fallback = null, source, ...props }) {
315
+ const queryClient = useQueryClient();
316
+ const persisted = useQuery(source.queryOptions).data ?? null;
317
+ const path = persisted?.path;
318
+ const [draft, setDraft] = React.useState(null);
319
+ const [sessionSent, setSessionSent] = React.useState(false);
320
+ /** The last draft handed to a save attempt; blocks duplicate autosaves. */
321
+ const attemptedDraftRef = React.useRef(null);
322
+ /** The last draft the host confirmed written. */
323
+ const savedDraftRef = React.useRef(null);
324
+ /** Outcome of the in-flight save, for the Send gate. */
325
+ const savePromiseRef = React.useRef(null);
326
+ /** The last projection this card rendered, kept for the sent snapshot. */
327
+ const lastShownRef = React.useRef(null);
328
+ const saveMutation = useMutation({
329
+ mutationFn: async (next) => {
330
+ if (!source.onChange) throw new Error(SAVE_UNAVAILABLE_MESSAGE);
331
+ if (path === void 0) throw new Error(FILE_MISSING_MESSAGE);
332
+ await source.onChange(path, next);
333
+ },
334
+ onMutate: async (next) => {
335
+ attemptedDraftRef.current = next;
336
+ await queryClient.cancelQueries({
337
+ queryKey: source.queryOptions.queryKey,
338
+ exact: true
339
+ });
340
+ },
341
+ onSuccess: (_data, next) => {
342
+ savedDraftRef.current = next;
343
+ },
344
+ onSettled: async (_data, error, next) => {
345
+ await queryClient.invalidateQueries({
346
+ queryKey: source.queryOptions.queryKey,
347
+ exact: true
348
+ });
349
+ if (!error) setDraft((current) => current === next ? null : current);
350
+ }
351
+ });
352
+ const { mutateAsync: mutateSaveAsync, isPending: savePending } = saveMutation;
353
+ const runSave = React.useCallback((next) => {
354
+ const settled = mutateSaveAsync(next).then(() => true, () => false);
355
+ savePromiseRef.current = settled;
356
+ return settled;
357
+ }, [mutateSaveAsync]);
358
+ const { mutateAsync: mutateSendAsync } = useMutation({
359
+ mutationFn: async () => {
360
+ if (!source.onSend) throw new Error(SEND_UNAVAILABLE_MESSAGE);
361
+ if (path === void 0) throw new Error(FILE_MISSING_MESSAGE);
362
+ await source.onSend(path);
363
+ },
364
+ onSuccess: () => queryClient.invalidateQueries({
365
+ queryKey: source.queryOptions.queryKey,
366
+ exact: true
367
+ })
368
+ });
369
+ const canSave = source.onChange != null;
370
+ const settled = persisted?.state === "sent" || persisted?.state === void 0 && sessionSent;
371
+ const runDebouncedSave = React.useEffectEvent((next) => {
372
+ runSave(next);
373
+ });
374
+ React.useEffect(() => {
375
+ if (!canSave || path === void 0 || settled || draft === null) return;
376
+ if (draft === savedDraftRef.current || draft === attemptedDraftRef.current) return;
377
+ if (savePending) return;
378
+ const timer = setTimeout(() => runDebouncedSave(draft), SAVE_DEBOUNCE_MS);
379
+ return () => clearTimeout(timer);
380
+ }, [
381
+ canSave,
382
+ draft,
383
+ path,
384
+ savePending,
385
+ settled
386
+ ]);
387
+ const send = React.useCallback(async () => {
388
+ if (savePromiseRef.current !== null && !await savePromiseRef.current) throw new Error(SEND_BLOCKED_MESSAGE);
389
+ const outstanding = draft;
390
+ if (outstanding !== null && outstanding !== savedDraftRef.current) {
391
+ if (!await runSave(outstanding)) throw new Error(SEND_BLOCKED_MESSAGE);
392
+ }
393
+ await mutateSendAsync();
394
+ if (persisted) lastShownRef.current = draft === null ? persisted : {
395
+ ...persisted,
396
+ ...draft
397
+ };
398
+ setSessionSent(true);
399
+ }, [
400
+ draft,
401
+ mutateSendAsync,
402
+ persisted,
403
+ runSave
404
+ ]);
405
+ const shown = persisted ?? (sessionSent ? lastShownRef.current : null);
406
+ if (!shown) return fallback;
407
+ const visible = draft ?? shown;
408
+ const state = shown.state ?? (sessionSent ? "sent" : "draft");
409
+ const saveState = saveMutation.isPending ? { status: "saving" } : saveMutation.isError ? {
410
+ status: "error",
411
+ message: formatErrorMessage(saveMutation.error),
412
+ onRetry: draft === null ? void 0 : () => void runSave(draft)
413
+ } : void 0;
414
+ return /* @__PURE__ */ jsx(WorkspaceCorrespondenceCard, {
415
+ ...props,
416
+ body: visible.body,
417
+ fields: visible.fields,
418
+ kind: shown.kind,
419
+ path: shown.path,
420
+ state,
421
+ saveState,
422
+ onChange: source.onChange ? setDraft : void 0,
423
+ onSend: source.onSend ? send : void 0,
424
+ onOpen: source.onOpen ? () => source.onOpen?.(shown.path) : void 0,
425
+ onDelete: source.onDelete ? () => source.onDelete?.(shown.path) : void 0
426
+ });
427
+ }
428
+ //#endregion
429
+ export { WorkspaceCorrespondenceCard, WorkspaceCorrespondenceFile };
@@ -0,0 +1,115 @@
1
+ import { ThinkFullAppPanel } from "./ThinkFullApp.js";
2
+ import { WorkspaceConceptQueryOptions } from "./WorkspaceConcept.js";
3
+ import { CardProps } from "../foundations/Card.js";
4
+ import * as React from "react";
5
+
6
+ //#region src/components/agents-sdk/WorkspaceExecution.d.ts
7
+ type WorkspaceExecutionParamType = "string" | "number" | "boolean";
8
+ interface WorkspaceExecutionParam {
9
+ name: string;
10
+ label: string;
11
+ type: WorkspaceExecutionParamType;
12
+ /**
13
+ * Whether the module's schema lists this property as required. This is a
14
+ * presentation hint only; the execution runtime owns argument validation.
15
+ */
16
+ required: boolean;
17
+ value?: string | number | boolean;
18
+ }
19
+ interface WorkspaceExecutionRun {
20
+ path: string;
21
+ label: string;
22
+ }
23
+ interface WorkspaceExecutionRunView extends WorkspaceExecutionRun {
24
+ onOpen?: () => void;
25
+ }
26
+ interface WorkspaceExecutionOutcome {
27
+ /** Serialized return value from the existing execution runtime. */
28
+ result: unknown;
29
+ logs: readonly string[];
30
+ /** Result and log files emitted when the runtime overflowed its inline bounds. */
31
+ runs: readonly WorkspaceExecutionRun[];
32
+ }
33
+ interface WorkspaceExecutionViewOutcome extends Omit<WorkspaceExecutionOutcome, "runs"> {
34
+ runs: readonly WorkspaceExecutionRunView[];
35
+ }
36
+ interface WorkspaceExecution {
37
+ /** Workspace path of the module file. */
38
+ path: string;
39
+ name: string;
40
+ description?: string;
41
+ /** Brand mark. Defaults to `TerminalIcon`. */
42
+ icon?: React.ReactNode;
43
+ parameters: readonly WorkspaceExecutionParam[];
44
+ /** Recent result peeks, newest first. Not a results directory. */
45
+ runs?: readonly WorkspaceExecutionRun[];
46
+ }
47
+ /** Data-only execution projection hydrated with card actions outside Query. */
48
+ interface WorkspaceExecutionView extends WorkspaceExecution {
49
+ runs?: readonly WorkspaceExecutionRunView[];
50
+ /**
51
+ * Runs the module with the submitted values. The card owns the run lifecycle;
52
+ * inline output and any overflow files enrich the completed row.
53
+ */
54
+ onRun?: (parameters: readonly WorkspaceExecutionParam[]) => Promise<WorkspaceExecutionViewOutcome>;
55
+ onOpen?: () => void;
56
+ onDelete?: () => void | Promise<void>;
57
+ }
58
+ interface WorkspaceExecutionSource {
59
+ queryOptions: WorkspaceConceptQueryOptions<readonly WorkspaceExecution[]>;
60
+ /** Runs the module with the submitted values and returns its visible outcome. */
61
+ onRun?: (path: string, parameters: readonly WorkspaceExecutionParam[]) => Promise<WorkspaceExecutionOutcome>;
62
+ onOpen?: (path: string) => void;
63
+ onDelete?: (path: string) => void | Promise<void>;
64
+ }
65
+ interface WorkspaceExecutionCardProps extends Omit<CardProps, "children" | "hover" | "size" | "title"> {
66
+ module: WorkspaceExecutionView;
67
+ }
68
+ interface WorkspaceExecutionFileProps extends Omit<WorkspaceExecutionCardProps, "module"> {
69
+ path: string;
70
+ source: WorkspaceExecutionSource;
71
+ fallback?: React.ReactNode;
72
+ }
73
+ interface WorkspaceExecutionsPanelProps extends Omit<React.HTMLAttributes<HTMLElement>, "children"> {
74
+ modules: readonly WorkspaceExecutionView[];
75
+ loading?: boolean;
76
+ /** Query failure to show instead of the empty state. Loaded modules win. */
77
+ error?: string;
78
+ onRetry?: () => void;
79
+ }
80
+ declare function WorkspaceExecutionCard({
81
+ module,
82
+ ...props
83
+ }: WorkspaceExecutionCardProps & {
84
+ ref?: React.Ref<HTMLDivElement>;
85
+ }): React.JSX.Element;
86
+ /**
87
+ * Compact inline card for one queried execution module.
88
+ */
89
+ declare function WorkspaceExecutionFile({
90
+ fallback,
91
+ path,
92
+ source,
93
+ ...props
94
+ }: WorkspaceExecutionFileProps & {
95
+ ref?: React.Ref<HTMLDivElement>;
96
+ }): string | number | bigint | boolean | React.JSX.Element | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null;
97
+ /**
98
+ * Workbench library. Same card as the inline placement. A query failure with
99
+ * nothing loaded renders as a quiet inline error, never as an empty library.
100
+ */
101
+ declare function WorkspaceExecutionsPanel({
102
+ className,
103
+ error,
104
+ loading,
105
+ modules,
106
+ onRetry,
107
+ ref,
108
+ ...props
109
+ }: WorkspaceExecutionsPanelProps & {
110
+ ref?: React.Ref<HTMLElement>;
111
+ }): React.JSX.Element;
112
+ /** Canonical workbench descriptor; hosts supply only the source adapter. */
113
+ declare function workspaceExecutionsPanel(source: WorkspaceExecutionSource): ThinkFullAppPanel;
114
+ //#endregion
115
+ export { WorkspaceExecution, WorkspaceExecutionCard, WorkspaceExecutionCardProps, WorkspaceExecutionFile, WorkspaceExecutionFileProps, WorkspaceExecutionOutcome, WorkspaceExecutionParam, WorkspaceExecutionParamType, WorkspaceExecutionRun, WorkspaceExecutionRunView, WorkspaceExecutionSource, WorkspaceExecutionView, WorkspaceExecutionViewOutcome, WorkspaceExecutionsPanel, WorkspaceExecutionsPanelProps, workspaceExecutionsPanel };