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