@stigmer/react 3.11.0 → 3.12.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.
- package/activity/useRecentActivity.d.ts +3 -2
- package/activity/useRecentActivity.d.ts.map +1 -1
- package/activity/useRecentActivity.js +3 -2
- package/activity/useRecentActivity.js.map +1 -1
- package/agent/AgentDetailView.d.ts +2 -12
- package/agent/AgentDetailView.d.ts.map +1 -1
- package/agent/AgentDetailView.js +10 -42
- package/agent/AgentDetailView.js.map +1 -1
- package/agent/internal/agentToInput.d.ts.map +1 -1
- package/agent/internal/agentToInput.js +0 -8
- package/agent/internal/agentToInput.js.map +1 -1
- package/agent-instance/AgentInstanceList.d.ts.map +1 -1
- package/agent-instance/AgentInstanceList.js +2 -1
- package/agent-instance/AgentInstanceList.js.map +1 -1
- package/api-key/ApiKeyListPanel.d.ts.map +1 -1
- package/api-key/ApiKeyListPanel.js +2 -1
- package/api-key/ApiKeyListPanel.js.map +1 -1
- package/attachment/AttachmentChipList.d.ts.map +1 -1
- package/attachment/AttachmentChipList.js +9 -8
- package/attachment/AttachmentChipList.js.map +1 -1
- package/attachment/AttachmentImageLightbox.d.ts.map +1 -1
- package/attachment/AttachmentImageLightbox.js +1 -1
- package/attachment/AttachmentImageLightbox.js.map +1 -1
- package/channel/AgentChannelsPanel.d.ts.map +1 -1
- package/channel/AgentChannelsPanel.js +2 -1
- package/channel/AgentChannelsPanel.js.map +1 -1
- package/channel/ChannelConversationsDialog.d.ts.map +1 -1
- package/channel/ChannelConversationsDialog.js +2 -1
- package/channel/ChannelConversationsDialog.js.map +1 -1
- package/channel/ChannelTemplatesDialog.d.ts.map +1 -1
- package/channel/ChannelTemplatesDialog.js +2 -1
- package/channel/ChannelTemplatesDialog.js.map +1 -1
- package/channel-app/internal.d.ts.map +1 -1
- package/channel-app/internal.js +2 -1
- package/channel-app/internal.js.map +1 -1
- package/composer/ComposerToolbar.d.ts.map +1 -1
- package/composer/ComposerToolbar.js +10 -7
- package/composer/ComposerToolbar.js.map +1 -1
- package/composer/ConfigureMenu.d.ts.map +1 -1
- package/composer/ConfigureMenu.js +2 -1
- package/composer/ConfigureMenu.js.map +1 -1
- package/composer/ContextChip.d.ts.map +1 -1
- package/composer/ContextChip.js +2 -1
- package/composer/ContextChip.js.map +1 -1
- package/composer/ContextPopover.d.ts.map +1 -1
- package/composer/ContextPopover.js +2 -1
- package/composer/ContextPopover.js.map +1 -1
- package/composer/SessionComposer.d.ts +13 -0
- package/composer/SessionComposer.d.ts.map +1 -1
- package/composer/SessionComposer.js +12 -2
- package/composer/SessionComposer.js.map +1 -1
- package/conversation/ConversationMediaAttachment.d.ts.map +1 -1
- package/conversation/ConversationMediaAttachment.js +2 -1
- package/conversation/ConversationMediaAttachment.js.map +1 -1
- package/conversation/ConversationTimelineView.d.ts.map +1 -1
- package/conversation/ConversationTimelineView.js +14 -4
- package/conversation/ConversationTimelineView.js.map +1 -1
- package/conversation/conversationPresentation.d.ts +28 -0
- package/conversation/conversationPresentation.d.ts.map +1 -1
- package/conversation/conversationPresentation.js +38 -1
- package/conversation/conversationPresentation.js.map +1 -1
- package/cursor-accounts/MemberCoverageTable.d.ts.map +1 -1
- package/cursor-accounts/MemberCoverageTable.js +6 -5
- package/cursor-accounts/MemberCoverageTable.js.map +1 -1
- package/dashboard/DashboardKPICards.d.ts.map +1 -1
- package/dashboard/DashboardKPICards.js +3 -1
- package/dashboard/DashboardKPICards.js.map +1 -1
- package/dependency-graph/DependencyTreeNode.d.ts.map +1 -1
- package/dependency-graph/DependencyTreeNode.js +1 -7
- package/dependency-graph/DependencyTreeNode.js.map +1 -1
- package/dependency-graph/types.d.ts +8 -20
- package/dependency-graph/types.d.ts.map +1 -1
- package/dependency-graph/useDependencyGraph.d.ts.map +1 -1
- package/dependency-graph/useDependencyGraph.js +2 -20
- package/dependency-graph/useDependencyGraph.js.map +1 -1
- package/environment/EnvironmentVariableEditor.d.ts.map +1 -1
- package/environment/EnvironmentVariableEditor.js +2 -1
- package/environment/EnvironmentVariableEditor.js.map +1 -1
- package/execution/ApprovalCard.d.ts.map +1 -1
- package/execution/ApprovalCard.js +1 -1
- package/execution/ApprovalCard.js.map +1 -1
- package/execution/ArtifactRowView.d.ts.map +1 -1
- package/execution/ArtifactRowView.js +2 -1
- package/execution/ArtifactRowView.js.map +1 -1
- package/execution/FilePathLink.d.ts +4 -4
- package/execution/FilePathLink.d.ts.map +1 -1
- package/execution/FilePathLink.js +4 -4
- package/execution/FilePathLink.js.map +1 -1
- package/execution/McpToolDetail.d.ts.map +1 -1
- package/execution/McpToolDetail.js +2 -1
- package/execution/McpToolDetail.js.map +1 -1
- package/execution/MessageAttachments.d.ts.map +1 -1
- package/execution/MessageAttachments.js +10 -8
- package/execution/MessageAttachments.js.map +1 -1
- package/execution/MessageEntry.d.ts.map +1 -1
- package/execution/MessageEntry.js +2 -1
- package/execution/MessageEntry.js.map +1 -1
- package/execution/PlanArtifactCard.d.ts.map +1 -1
- package/execution/PlanArtifactCard.js +7 -4
- package/execution/PlanArtifactCard.js.map +1 -1
- package/execution/ToolCallDetail.d.ts.map +1 -1
- package/execution/ToolCallDetail.js +1 -1
- package/execution/ToolCallDetail.js.map +1 -1
- package/execution/ToolCallItem.d.ts.map +1 -1
- package/execution/ToolCallItem.js +5 -1
- package/execution/ToolCallItem.js.map +1 -1
- package/execution/WriteBackCard.d.ts.map +1 -1
- package/execution/WriteBackCard.js +6 -4
- package/execution/WriteBackCard.js.map +1 -1
- package/execution/artifact-row-item.d.ts +1 -1
- package/execution/artifact-row-item.d.ts.map +1 -1
- package/file-reference/FileReferenceChipList.d.ts.map +1 -1
- package/file-reference/FileReferenceChipList.js +6 -1
- package/file-reference/FileReferenceChipList.js.map +1 -1
- package/iam-policy/OrgMembersPanel.d.ts.map +1 -1
- package/iam-policy/OrgMembersPanel.js +6 -5
- package/iam-policy/OrgMembersPanel.js.map +1 -1
- package/iam-policy/ProviderBadge.d.ts.map +1 -1
- package/iam-policy/ProviderBadge.js +3 -2
- package/iam-policy/ProviderBadge.js.map +1 -1
- package/iam-policy/RoleSelector.d.ts.map +1 -1
- package/iam-policy/RoleSelector.js +1 -1
- package/iam-policy/RoleSelector.js.map +1 -1
- package/identity-provider/IdentityProviderListPanel.d.ts.map +1 -1
- package/identity-provider/IdentityProviderListPanel.js +2 -1
- package/identity-provider/IdentityProviderListPanel.js.map +1 -1
- package/index.d.ts +0 -2
- package/index.d.ts.map +1 -1
- package/index.js +0 -6
- package/index.js.map +1 -1
- package/internal/truncated-text.d.ts +17 -0
- package/internal/truncated-text.d.ts.map +1 -0
- package/internal/truncated-text.js +27 -0
- package/internal/truncated-text.js.map +1 -0
- package/invitation/InvitationManager.d.ts.map +1 -1
- package/invitation/InvitationManager.js +4 -3
- package/invitation/InvitationManager.js.map +1 -1
- package/library/ScopeToggle.d.ts.map +1 -1
- package/library/ScopeToggle.js +10 -2
- package/library/ScopeToggle.js.map +1 -1
- package/library/VisibilitySelector.d.ts.map +1 -1
- package/library/VisibilitySelector.js +2 -1
- package/library/VisibilitySelector.js.map +1 -1
- package/library/useExportResource.d.ts +3 -4
- package/library/useExportResource.d.ts.map +1 -1
- package/library/useExportResource.js +1 -1
- package/library/useExportResource.js.map +1 -1
- package/manifest/EditResourceYamlDialog.d.ts.map +1 -1
- package/manifest/EditResourceYamlDialog.js.map +1 -1
- package/mcp-server/McpServerConfigPanel.d.ts +30 -1
- package/mcp-server/McpServerConfigPanel.d.ts.map +1 -1
- package/mcp-server/McpServerConfigPanel.js +18 -8
- package/mcp-server/McpServerConfigPanel.js.map +1 -1
- package/mcp-server/McpServerConnectDialog.d.ts +12 -1
- package/mcp-server/McpServerConnectDialog.d.ts.map +1 -1
- package/mcp-server/McpServerConnectDialog.js +8 -7
- package/mcp-server/McpServerConnectDialog.js.map +1 -1
- package/mcp-server/McpServerDetailView.d.ts.map +1 -1
- package/mcp-server/McpServerDetailView.js +4 -4
- package/mcp-server/McpServerDetailView.js.map +1 -1
- package/mcp-server/McpServerPicker.d.ts.map +1 -1
- package/mcp-server/McpServerPicker.js +86 -5
- package/mcp-server/McpServerPicker.js.map +1 -1
- package/mcp-server/McpToolSelector.d.ts.map +1 -1
- package/mcp-server/McpToolSelector.js +2 -1
- package/mcp-server/McpToolSelector.js.map +1 -1
- package/mcp-server/VendorApprovalBlockedNotice.d.ts +77 -0
- package/mcp-server/VendorApprovalBlockedNotice.d.ts.map +1 -0
- package/mcp-server/VendorApprovalBlockedNotice.js +62 -0
- package/mcp-server/VendorApprovalBlockedNotice.js.map +1 -0
- package/mcp-server/mcpServerSetupReducer.d.ts +18 -0
- package/mcp-server/mcpServerSetupReducer.d.ts.map +1 -1
- package/mcp-server/mcpServerSetupReducer.js +6 -0
- package/mcp-server/mcpServerSetupReducer.js.map +1 -1
- package/mcp-server/useMcpServerSetup.d.ts.map +1 -1
- package/mcp-server/useMcpServerSetup.js +7 -0
- package/mcp-server/useMcpServerSetup.js.map +1 -1
- package/oauth-app/OAuthAppListPanel.d.ts.map +1 -1
- package/oauth-app/OAuthAppListPanel.js +2 -1
- package/oauth-app/OAuthAppListPanel.js.map +1 -1
- package/package.json +4 -4
- package/platform-client/PlatformClientListPanel.d.ts.map +1 -1
- package/platform-client/PlatformClientListPanel.js +3 -2
- package/platform-client/PlatformClientListPanel.js.map +1 -1
- package/pricing-governance/BaselineEditor.d.ts.map +1 -1
- package/pricing-governance/BaselineEditor.js +7 -1
- package/pricing-governance/BaselineEditor.js.map +1 -1
- package/pricing-governance/ModelCatalogPanel.d.ts.map +1 -1
- package/pricing-governance/ModelCatalogPanel.js +2 -1
- package/pricing-governance/ModelCatalogPanel.js.map +1 -1
- package/pricing-governance/PricingGovernanceConsole.d.ts.map +1 -1
- package/pricing-governance/PricingGovernanceConsole.js +2 -1
- package/pricing-governance/PricingGovernanceConsole.js.map +1 -1
- package/pricing-governance/PricingGovernancePanel.d.ts.map +1 -1
- package/pricing-governance/PricingGovernancePanel.js +2 -1
- package/pricing-governance/PricingGovernancePanel.js.map +1 -1
- package/resource-workbench/components/StatusBadge.d.ts.map +1 -1
- package/resource-workbench/components/StatusBadge.js +2 -1
- package/resource-workbench/components/StatusBadge.js.map +1 -1
- package/schedule/CadenceField.d.ts.map +1 -1
- package/schedule/CadenceField.js +15 -8
- package/schedule/CadenceField.js.map +1 -1
- package/schedule/ScheduleRunsTable.d.ts.map +1 -1
- package/schedule/ScheduleRunsTable.js +3 -2
- package/schedule/ScheduleRunsTable.js.map +1 -1
- package/session/PlanEditor.d.ts.map +1 -1
- package/session/PlanEditor.js +3 -5
- package/session/PlanEditor.js.map +1 -1
- package/sharing/AgentShareList.d.ts.map +1 -1
- package/sharing/AgentShareList.js +3 -1
- package/sharing/AgentShareList.js.map +1 -1
- package/sharing/ShareAgentDialog.d.ts.map +1 -1
- package/sharing/ShareAgentDialog.js +2 -1
- package/sharing/ShareAgentDialog.js.map +1 -1
- package/skill/SkillDetailView.d.ts.map +1 -1
- package/skill/SkillDetailView.js +3 -2
- package/skill/SkillDetailView.js.map +1 -1
- package/src/__tests__/helpers/open-menu.ts +88 -0
- package/src/__tests__/portal-container.test.tsx +3 -3
- package/src/activity/useRecentActivity.ts +3 -2
- package/src/agent/AgentDetailView.tsx +6 -130
- package/src/agent/internal/__tests__/agentToInput.test.ts +2 -11
- package/src/agent/internal/agentToInput.ts +0 -11
- package/src/agent-instance/AgentInstanceList.tsx +5 -6
- package/src/agent-instance/__tests__/AgentInstanceList.test.tsx +5 -4
- package/src/api-key/ApiKeyListPanel.tsx +11 -3
- package/src/attachment/AttachmentChipList.tsx +74 -65
- package/src/attachment/AttachmentImageLightbox.tsx +5 -4
- package/src/attachment/__tests__/AttachmentChipList.test.tsx +4 -3
- package/src/channel/AgentChannelsPanel.tsx +5 -6
- package/src/channel/ChannelConversationsDialog.tsx +5 -3
- package/src/channel/ChannelTemplatesDialog.tsx +5 -6
- package/src/channel/__tests__/AgentChannelsPanel.test.tsx +14 -9
- package/src/channel-app/internal.tsx +5 -6
- package/src/composer/ComposerToolbar.tsx +122 -90
- package/src/composer/ConfigureMenu.tsx +33 -24
- package/src/composer/ContextChip.tsx +2 -3
- package/src/composer/ContextPopover.tsx +27 -18
- package/src/composer/SessionComposer.tsx +41 -9
- package/src/composer/__tests__/SessionComposer-agentSetupError.test.tsx +124 -0
- package/src/composer/__tests__/SessionComposer-lockAgent.test.tsx +4 -9
- package/src/conversation/ConversationMediaAttachment.tsx +2 -2
- package/src/conversation/ConversationTimelineView.tsx +19 -2
- package/src/conversation/__tests__/ConversationTimelineView.test.tsx +106 -3
- package/src/conversation/conversationPresentation.ts +52 -1
- package/src/cursor-accounts/MemberCoverageTable.tsx +15 -13
- package/src/cursor-accounts/__tests__/CursorAccountsConsole.test.tsx +4 -4
- package/src/dashboard/DashboardKPICards.tsx +2 -1
- package/src/dependency-graph/DependencyTreeNode.tsx +1 -7
- package/src/dependency-graph/__tests__/useDependencyGraph.test.ts +18 -34
- package/src/dependency-graph/types.ts +8 -20
- package/src/dependency-graph/useDependencyGraph.ts +2 -22
- package/src/environment/EnvironmentVariableEditor.tsx +17 -6
- package/src/execution/ApprovalCard.tsx +1 -3
- package/src/execution/ArtifactRowView.tsx +68 -48
- package/src/execution/FilePathLink.tsx +43 -27
- package/src/execution/McpToolDetail.tsx +6 -2
- package/src/execution/MessageAttachments.tsx +57 -41
- package/src/execution/MessageEntry.tsx +22 -15
- package/src/execution/PlanArtifactCard.tsx +25 -18
- package/src/execution/ToolCallDetail.tsx +1 -4
- package/src/execution/ToolCallItem.tsx +18 -7
- package/src/execution/WriteBackCard.tsx +38 -29
- package/src/execution/__tests__/ArtifactRow.test.tsx +6 -2
- package/src/execution/__tests__/ArtifactRowView.test.tsx +5 -2
- package/src/execution/__tests__/FilePathLink.test.tsx +10 -6
- package/src/execution/__tests__/FileReviewCard.test.tsx +2 -1
- package/src/execution/__tests__/MessageEntry-attachments.test.tsx +3 -2
- package/src/execution/__tests__/MessageThread.test.tsx +6 -1
- package/src/execution/__tests__/artifact-row-tooltips.layout.test.tsx +115 -0
- package/src/execution/artifact-row-item.ts +1 -1
- package/src/file-reference/FileReferenceChipList.tsx +29 -17
- package/src/file-reference/__tests__/FileReferenceChipList.test.tsx +5 -2
- package/src/iam-policy/OrgMembersPanel.tsx +26 -19
- package/src/iam-policy/ProviderBadge.tsx +17 -10
- package/src/iam-policy/RoleSelector.tsx +0 -1
- package/src/identity-provider/IdentityProviderListPanel.tsx +11 -3
- package/src/index.ts +0 -82
- package/src/internal/__tests__/truncated-text.layout.test.tsx +68 -0
- package/src/internal/__tests__/truncated-text.test.tsx +33 -0
- package/src/internal/truncated-text.tsx +81 -0
- package/src/invitation/InvitationManager.tsx +18 -5
- package/src/library/ScopeToggle.tsx +14 -2
- package/src/library/VisibilitySelector.tsx +21 -14
- package/src/library/useExportResource.ts +3 -4
- package/src/manifest/EditResourceYamlDialog.tsx +1 -2
- package/src/manifest/__tests__/ApplyManifestDialog.test.tsx +2 -2
- package/src/manifest/__tests__/EditResourceYamlDialog.test.tsx +9 -9
- package/src/mcp-server/McpServerConfigPanel.tsx +79 -37
- package/src/mcp-server/McpServerConnectDialog.tsx +41 -5
- package/src/mcp-server/McpServerDetailView.tsx +23 -39
- package/src/mcp-server/McpServerPicker.tsx +99 -7
- package/src/mcp-server/McpToolSelector.tsx +12 -7
- package/src/mcp-server/VendorApprovalBlockedNotice.tsx +221 -0
- package/src/mcp-server/__tests__/McpServerPicker.test.tsx +504 -0
- package/src/mcp-server/__tests__/VendorApprovalBlocked.surfaces.test.tsx +321 -0
- package/src/mcp-server/__tests__/VendorApprovalBlockedNotice.test.tsx +154 -0
- package/src/mcp-server/mcpServerSetupReducer.ts +24 -0
- package/src/mcp-server/useMcpServerSetup.ts +9 -0
- package/src/oauth-app/OAuthAppListPanel.tsx +11 -3
- package/src/platform-client/PlatformClientListPanel.tsx +35 -18
- package/src/pricing-governance/BaselineEditor.tsx +20 -0
- package/src/pricing-governance/ModelCatalogPanel.tsx +9 -5
- package/src/pricing-governance/PricingGovernanceConsole.tsx +9 -5
- package/src/pricing-governance/PricingGovernancePanel.tsx +13 -4
- package/src/pricing-governance/__tests__/ModelCatalogPanel.test.tsx +37 -0
- package/src/resource-workbench/components/StatusBadge.tsx +7 -3
- package/src/schedule/CadenceField.tsx +38 -27
- package/src/schedule/ScheduleRunsTable.tsx +23 -11
- package/src/schedule/__tests__/cadence-tooltips.layout.test.tsx +86 -0
- package/src/session/PlanEditor.tsx +9 -8
- package/src/sharing/AgentShareList.tsx +28 -22
- package/src/sharing/ShareAgentDialog.tsx +5 -6
- package/src/sharing/__tests__/AgentShareList.test.tsx +4 -4
- package/src/skill/SkillDetailView.tsx +23 -12
- package/src/version-history/VersionTimelineEntry.tsx +21 -12
- package/src/workflow/CanvasTransitionEdge.tsx +23 -16
- package/src/workflow/ExecutionActiveTaskIndicator.tsx +74 -59
- package/src/workflow/TaskPickerPopover.tsx +0 -1
- package/src/workflow/WorkflowCanvasEditor.tsx +95 -64
- package/src/workflow/WorkflowNode.tsx +13 -6
- package/src/workflow/WorkflowTaskApprovalSummary.tsx +18 -11
- package/src/workflow/WorkflowTaskList.tsx +2 -2
- package/src/workflow/WorkflowVersionBadge.tsx +33 -18
- package/src/workflow/WorkflowVersionTimeline.tsx +7 -6
- package/src/workflow/__tests__/WorkflowTaskApprovalSummary.test.tsx +3 -1
- package/src/workflow/__tests__/structured-data-viewer.test.tsx +5 -2
- package/src/workflow/execution-comparison/ExecutionComparisonView.tsx +5 -3
- package/src/workflow/execution-comparison/TaskComparisonTable.tsx +12 -5
- package/src/workflow/execution-history/ExecutionHistoryTable.tsx +24 -15
- package/src/workflow/inspector/InspectorHeader.tsx +20 -11
- package/src/workflow/inspector/NestedTaskList.tsx +18 -11
- package/src/workflow/inspector/WorkflowSummaryPanel.tsx +5 -3
- package/src/workflow/inspector/tabs/BranchesTab.tsx +61 -31
- package/src/workflow/instance/WorkflowInstanceList.tsx +5 -6
- package/src/workflow/instance/__tests__/WorkflowInstanceList.test.tsx +5 -4
- package/src/workflow/node-shell/DiffBadge.tsx +18 -11
- package/src/workflow/node-shell/ExecutionBadge.tsx +73 -46
- package/src/workflow/node-shell/NodeActions.tsx +128 -94
- package/src/workflow/task-detail/StructuredDataViewer.tsx +4 -2
- package/src/workspace/EditorTabs.tsx +102 -85
- package/src/workspace/ExplorerTree.tsx +47 -30
- package/src/workspace/FileViewer.tsx +11 -3
- package/src/workspace/PanelChip.tsx +32 -23
- package/src/workspace/WorkspaceEditor.tsx +21 -9
- package/src/workspace/WorkspaceSummary.tsx +21 -12
- package/src/workspace/WorkspaceSurface.tsx +86 -61
- package/src/workspace/__tests__/EditorTabs.test.tsx +5 -2
- package/src/workspace/__tests__/WorkspaceSurface.test.tsx +5 -2
- package/styles.css +1 -1
- package/version-history/VersionTimelineEntry.d.ts.map +1 -1
- package/version-history/VersionTimelineEntry.js +2 -1
- package/version-history/VersionTimelineEntry.js.map +1 -1
- package/workflow/CanvasTransitionEdge.d.ts +1 -1
- package/workflow/CanvasTransitionEdge.d.ts.map +1 -1
- package/workflow/CanvasTransitionEdge.js +3 -2
- package/workflow/CanvasTransitionEdge.js.map +1 -1
- package/workflow/ExecutionActiveTaskIndicator.d.ts.map +1 -1
- package/workflow/ExecutionActiveTaskIndicator.js +12 -11
- package/workflow/ExecutionActiveTaskIndicator.js.map +1 -1
- package/workflow/TaskPickerPopover.js +1 -1
- package/workflow/TaskPickerPopover.js.map +1 -1
- package/workflow/WorkflowCanvasEditor.d.ts.map +1 -1
- package/workflow/WorkflowCanvasEditor.js +9 -2
- package/workflow/WorkflowCanvasEditor.js.map +1 -1
- package/workflow/WorkflowNode.d.ts.map +1 -1
- package/workflow/WorkflowNode.js +2 -1
- package/workflow/WorkflowNode.js.map +1 -1
- package/workflow/WorkflowTaskApprovalSummary.d.ts.map +1 -1
- package/workflow/WorkflowTaskApprovalSummary.js +6 -4
- package/workflow/WorkflowTaskApprovalSummary.js.map +1 -1
- package/workflow/WorkflowTaskList.js +2 -2
- package/workflow/WorkflowTaskList.js.map +1 -1
- package/workflow/WorkflowVersionBadge.d.ts.map +1 -1
- package/workflow/WorkflowVersionBadge.js +2 -1
- package/workflow/WorkflowVersionBadge.js.map +1 -1
- package/workflow/WorkflowVersionTimeline.d.ts.map +1 -1
- package/workflow/WorkflowVersionTimeline.js +2 -1
- package/workflow/WorkflowVersionTimeline.js.map +1 -1
- package/workflow/execution-comparison/ExecutionComparisonView.d.ts.map +1 -1
- package/workflow/execution-comparison/ExecutionComparisonView.js +2 -1
- package/workflow/execution-comparison/ExecutionComparisonView.js.map +1 -1
- package/workflow/execution-comparison/TaskComparisonTable.d.ts.map +1 -1
- package/workflow/execution-comparison/TaskComparisonTable.js +2 -1
- package/workflow/execution-comparison/TaskComparisonTable.js.map +1 -1
- package/workflow/execution-history/ExecutionHistoryTable.d.ts.map +1 -1
- package/workflow/execution-history/ExecutionHistoryTable.js +6 -4
- package/workflow/execution-history/ExecutionHistoryTable.js.map +1 -1
- package/workflow/inspector/InspectorHeader.d.ts.map +1 -1
- package/workflow/inspector/InspectorHeader.js +4 -2
- package/workflow/inspector/InspectorHeader.js.map +1 -1
- package/workflow/inspector/NestedTaskList.d.ts.map +1 -1
- package/workflow/inspector/NestedTaskList.js +2 -1
- package/workflow/inspector/NestedTaskList.js.map +1 -1
- package/workflow/inspector/WorkflowSummaryPanel.d.ts.map +1 -1
- package/workflow/inspector/WorkflowSummaryPanel.js +2 -1
- package/workflow/inspector/WorkflowSummaryPanel.js.map +1 -1
- package/workflow/inspector/tabs/BranchesTab.d.ts.map +1 -1
- package/workflow/inspector/tabs/BranchesTab.js +5 -2
- package/workflow/inspector/tabs/BranchesTab.js.map +1 -1
- package/workflow/instance/WorkflowInstanceList.d.ts.map +1 -1
- package/workflow/instance/WorkflowInstanceList.js +2 -1
- package/workflow/instance/WorkflowInstanceList.js.map +1 -1
- package/workflow/node-shell/DiffBadge.d.ts.map +1 -1
- package/workflow/node-shell/DiffBadge.js +3 -2
- package/workflow/node-shell/DiffBadge.js.map +1 -1
- package/workflow/node-shell/ExecutionBadge.d.ts.map +1 -1
- package/workflow/node-shell/ExecutionBadge.js +5 -4
- package/workflow/node-shell/ExecutionBadge.js.map +1 -1
- package/workflow/node-shell/NodeActions.d.ts.map +1 -1
- package/workflow/node-shell/NodeActions.js +12 -11
- package/workflow/node-shell/NodeActions.js.map +1 -1
- package/workflow/task-detail/StructuredDataViewer.d.ts.map +1 -1
- package/workflow/task-detail/StructuredDataViewer.js +5 -1
- package/workflow/task-detail/StructuredDataViewer.js.map +1 -1
- package/workspace/EditorTabs.d.ts.map +1 -1
- package/workspace/EditorTabs.js +38 -37
- package/workspace/EditorTabs.js.map +1 -1
- package/workspace/ExplorerTree.d.ts.map +1 -1
- package/workspace/ExplorerTree.js +2 -1
- package/workspace/ExplorerTree.js.map +1 -1
- package/workspace/FileViewer.d.ts.map +1 -1
- package/workspace/FileViewer.js +2 -1
- package/workspace/FileViewer.js.map +1 -1
- package/workspace/PanelChip.d.ts.map +1 -1
- package/workspace/PanelChip.js +2 -1
- package/workspace/PanelChip.js.map +1 -1
- package/workspace/WorkspaceEditor.d.ts.map +1 -1
- package/workspace/WorkspaceEditor.js +2 -1
- package/workspace/WorkspaceEditor.js.map +1 -1
- package/workspace/WorkspaceSummary.d.ts.map +1 -1
- package/workspace/WorkspaceSummary.js +7 -2
- package/workspace/WorkspaceSummary.js.map +1 -1
- package/workspace/WorkspaceSurface.d.ts.map +1 -1
- package/workspace/WorkspaceSurface.js +12 -11
- package/workspace/WorkspaceSurface.js.map +1 -1
- package/datastore/CollectionRecordsBrowser.d.ts +0 -34
- package/datastore/CollectionRecordsBrowser.d.ts.map +0 -1
- package/datastore/CollectionRecordsBrowser.js +0 -223
- package/datastore/CollectionRecordsBrowser.js.map +0 -1
- package/datastore/CollectionSchemaView.d.ts +0 -29
- package/datastore/CollectionSchemaView.d.ts.map +0 -1
- package/datastore/CollectionSchemaView.js +0 -93
- package/datastore/CollectionSchemaView.js.map +0 -1
- package/datastore/DatastoreDetailView.d.ts +0 -44
- package/datastore/DatastoreDetailView.d.ts.map +0 -1
- package/datastore/DatastoreDetailView.js +0 -76
- package/datastore/DatastoreDetailView.js.map +0 -1
- package/datastore/DatastoreSyncReport.d.ts +0 -19
- package/datastore/DatastoreSyncReport.d.ts.map +0 -1
- package/datastore/DatastoreSyncReport.js +0 -45
- package/datastore/DatastoreSyncReport.js.map +0 -1
- package/datastore/DeleteDatastoreDialog.d.ts +0 -35
- package/datastore/DeleteDatastoreDialog.d.ts.map +0 -1
- package/datastore/DeleteDatastoreDialog.js +0 -90
- package/datastore/DeleteDatastoreDialog.js.map +0 -1
- package/datastore/FieldValueControl.d.ts +0 -55
- package/datastore/FieldValueControl.d.ts.map +0 -1
- package/datastore/FieldValueControl.js +0 -138
- package/datastore/FieldValueControl.js.map +0 -1
- package/datastore/RecordFilterBuilder.d.ts +0 -37
- package/datastore/RecordFilterBuilder.d.ts.map +0 -1
- package/datastore/RecordFilterBuilder.js +0 -122
- package/datastore/RecordFilterBuilder.js.map +0 -1
- package/datastore/RecordFormPanel.d.ts +0 -45
- package/datastore/RecordFormPanel.d.ts.map +0 -1
- package/datastore/RecordFormPanel.js +0 -215
- package/datastore/RecordFormPanel.js.map +0 -1
- package/datastore/index.d.ts +0 -43
- package/datastore/index.d.ts.map +0 -1
- package/datastore/index.js +0 -22
- package/datastore/index.js.map +0 -1
- package/datastore/recordFilter.d.ts +0 -62
- package/datastore/recordFilter.d.ts.map +0 -1
- package/datastore/recordFilter.js +0 -104
- package/datastore/recordFilter.js.map +0 -1
- package/datastore/recordValues.d.ts +0 -85
- package/datastore/recordValues.d.ts.map +0 -1
- package/datastore/recordValues.js +0 -282
- package/datastore/recordValues.js.map +0 -1
- package/datastore/useDatastore.d.ts +0 -39
- package/datastore/useDatastore.d.ts.map +0 -1
- package/datastore/useDatastore.js +0 -44
- package/datastore/useDatastore.js.map +0 -1
- package/datastore/useDatastoreCount.d.ts +0 -50
- package/datastore/useDatastoreCount.d.ts.map +0 -1
- package/datastore/useDatastoreCount.js +0 -27
- package/datastore/useDatastoreCount.js.map +0 -1
- package/datastore/useDatastoreDescription.d.ts +0 -54
- package/datastore/useDatastoreDescription.d.ts.map +0 -1
- package/datastore/useDatastoreDescription.js +0 -50
- package/datastore/useDatastoreDescription.js.map +0 -1
- package/datastore/useDatastoreList.d.ts +0 -57
- package/datastore/useDatastoreList.d.ts.map +0 -1
- package/datastore/useDatastoreList.js +0 -29
- package/datastore/useDatastoreList.js.map +0 -1
- package/datastore/useDatastoreSearch.d.ts +0 -19
- package/datastore/useDatastoreSearch.d.ts.map +0 -1
- package/datastore/useDatastoreSearch.js +0 -22
- package/datastore/useDatastoreSearch.js.map +0 -1
- package/datastore/useDeleteDatastore.d.ts +0 -53
- package/datastore/useDeleteDatastore.d.ts.map +0 -1
- package/datastore/useDeleteDatastore.js +0 -40
- package/datastore/useDeleteDatastore.js.map +0 -1
- package/datastore/useDeleteRecord.d.ts +0 -34
- package/datastore/useDeleteRecord.d.ts.map +0 -1
- package/datastore/useDeleteRecord.js +0 -43
- package/datastore/useDeleteRecord.js.map +0 -1
- package/datastore/useInsertRecord.d.ts +0 -50
- package/datastore/useInsertRecord.d.ts.map +0 -1
- package/datastore/useInsertRecord.js +0 -55
- package/datastore/useInsertRecord.js.map +0 -1
- package/datastore/useRecordCollection.d.ts +0 -104
- package/datastore/useRecordCollection.d.ts.map +0 -1
- package/datastore/useRecordCollection.js +0 -136
- package/datastore/useRecordCollection.js.map +0 -1
- package/datastore/useRecordList.d.ts +0 -66
- package/datastore/useRecordList.d.ts.map +0 -1
- package/datastore/useRecordList.js +0 -58
- package/datastore/useRecordList.js.map +0 -1
- package/datastore/useUpdateRecord.d.ts +0 -52
- package/datastore/useUpdateRecord.d.ts.map +0 -1
- package/datastore/useUpdateRecord.js +0 -55
- package/datastore/useUpdateRecord.js.map +0 -1
- package/src/agent/__tests__/AgentDetailView.datastores.test.tsx +0 -166
- package/src/datastore/CollectionRecordsBrowser.tsx +0 -570
- package/src/datastore/CollectionSchemaView.tsx +0 -247
- package/src/datastore/DatastoreDetailView.tsx +0 -201
- package/src/datastore/DatastoreSyncReport.tsx +0 -105
- package/src/datastore/DeleteDatastoreDialog.tsx +0 -202
- package/src/datastore/FieldValueControl.tsx +0 -289
- package/src/datastore/RecordFilterBuilder.tsx +0 -422
- package/src/datastore/RecordFormPanel.tsx +0 -432
- package/src/datastore/__tests__/CollectionRecordsBrowser.test.tsx +0 -245
- package/src/datastore/__tests__/DeleteDatastoreDialog.test.tsx +0 -133
- package/src/datastore/__tests__/FieldValueControl.test.tsx +0 -160
- package/src/datastore/__tests__/RecordFilterBuilder.test.tsx +0 -155
- package/src/datastore/__tests__/RecordFormPanel.test.tsx +0 -227
- package/src/datastore/__tests__/recordFilter.test.ts +0 -169
- package/src/datastore/__tests__/recordMutations.test.tsx +0 -195
- package/src/datastore/__tests__/recordValues.test.ts +0 -359
- package/src/datastore/__tests__/schemaAndSyncViews.test.tsx +0 -142
- package/src/datastore/__tests__/useDatastoreDescription.test.tsx +0 -143
- package/src/datastore/__tests__/useRecordCollection.test.tsx +0 -250
- package/src/datastore/__tests__/useRecordList.test.tsx +0 -85
- package/src/datastore/index.ts +0 -111
- package/src/datastore/recordFilter.ts +0 -154
- package/src/datastore/recordValues.ts +0 -327
- package/src/datastore/useDatastore.ts +0 -67
- package/src/datastore/useDatastoreCount.ts +0 -69
- package/src/datastore/useDatastoreDescription.ts +0 -90
- package/src/datastore/useDatastoreList.ts +0 -79
- package/src/datastore/useDatastoreSearch.ts +0 -39
- package/src/datastore/useDeleteDatastore.ts +0 -87
- package/src/datastore/useDeleteRecord.ts +0 -77
- package/src/datastore/useInsertRecord.ts +0 -92
- package/src/datastore/useRecordCollection.ts +0 -256
- package/src/datastore/useRecordList.ts +0 -131
- package/src/datastore/useUpdateRecord.ts +0 -95
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { cn } from "@stigmer/theme";
|
|
4
4
|
import { Popover } from "@base-ui/react/popover";
|
|
5
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from "../internal/tooltip.js";
|
|
5
6
|
import { useStigmerPortalContainer } from "../portal-container.js";
|
|
6
7
|
import { ConfigureIcon } from "./icons.js";
|
|
7
8
|
|
|
@@ -71,31 +72,39 @@ export function ConfigureMenu({
|
|
|
71
72
|
|
|
72
73
|
return (
|
|
73
74
|
<Popover.Root open={open} onOpenChange={handleOpenChange}>
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
75
|
+
{/* The tooltip trigger is a wrapper span, not the popover trigger
|
|
76
|
+
itself: `disabled` adds `pointer-events-none` to the button, so
|
|
77
|
+
only the span keeps hover — the icon's name stays discoverable
|
|
78
|
+
while the composer is disabled. */}
|
|
79
|
+
<Tooltip>
|
|
80
|
+
<TooltipTrigger render={<span className="stg:inline-flex" />}>
|
|
81
|
+
<Popover.Trigger
|
|
82
|
+
disabled={disabled}
|
|
83
|
+
className={cn(
|
|
84
|
+
"stg:inline-flex stg:h-8 stg:w-8 stg:items-center stg:justify-center stg:rounded-md stg:text-xs stg:transition-colors",
|
|
85
|
+
"stg:text-muted-foreground stg:hover:text-foreground stg:hover:bg-accent-hover",
|
|
86
|
+
"stg:disabled:pointer-events-none stg:disabled:opacity-50",
|
|
87
|
+
)}
|
|
88
|
+
aria-label="Configure agent, tools, and skills"
|
|
89
|
+
>
|
|
90
|
+
<span className="stg:relative">
|
|
91
|
+
<ConfigureIcon />
|
|
92
|
+
{totalCount > 0 && (
|
|
93
|
+
<span className="stg:absolute stg:-right-1.5 stg:-top-1.5 stg:flex stg:h-3.5 stg:min-w-3.5 stg:items-center stg:justify-center stg:rounded-full stg:bg-primary stg:px-0.5 stg:text-[0.5rem] stg:font-medium stg:leading-none stg:text-primary-foreground">
|
|
94
|
+
{totalCount}
|
|
95
|
+
</span>
|
|
96
|
+
)}
|
|
97
|
+
{hasWarning && totalCount === 0 && (
|
|
98
|
+
<span
|
|
99
|
+
className="stg:absolute stg:-right-0.5 stg:-top-0.5 stg:inline-block stg:h-2 stg:w-2 stg:rounded-full stg:bg-warning"
|
|
100
|
+
aria-label="Configuration needed"
|
|
101
|
+
/>
|
|
102
|
+
)}
|
|
89
103
|
</span>
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
aria-label="Configuration needed"
|
|
95
|
-
/>
|
|
96
|
-
)}
|
|
97
|
-
</span>
|
|
98
|
-
</Popover.Trigger>
|
|
104
|
+
</Popover.Trigger>
|
|
105
|
+
</TooltipTrigger>
|
|
106
|
+
<TooltipContent side="top">Configure</TooltipContent>
|
|
107
|
+
</Tooltip>
|
|
99
108
|
<Popover.Portal container={portalContainer}>
|
|
100
109
|
<Popover.Positioner sideOffset={8} align="start">
|
|
101
110
|
<Popover.Popup
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { cn } from "@stigmer/theme";
|
|
2
|
+
import { TruncatedText } from "../internal/truncated-text.js";
|
|
2
3
|
import { ChipSpinner, XIcon } from "./icons.js";
|
|
3
4
|
|
|
4
5
|
export interface ChipItem {
|
|
@@ -60,9 +61,7 @@ export function ContextChip({
|
|
|
60
61
|
<span className="stg:text-[0.55rem] stg:font-medium stg:uppercase stg:tracking-wider stg:text-muted-foreground">
|
|
61
62
|
{CHIP_TYPE_LABELS[type]}
|
|
62
63
|
</span>
|
|
63
|
-
<
|
|
64
|
-
{label}
|
|
65
|
-
</span>
|
|
64
|
+
<TruncatedText text={label} className="stg:max-w-[120px]" />
|
|
66
65
|
{detail != null && (
|
|
67
66
|
<span className="stg:shrink-0 stg:text-[0.6rem] stg:font-medium stg:text-muted-foreground">
|
|
68
67
|
{detail}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { cn } from "@stigmer/theme";
|
|
2
2
|
import { Popover } from "@base-ui/react/popover";
|
|
3
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from "../internal/tooltip.js";
|
|
3
4
|
import { useStigmerPortalContainer } from "../portal-container.js";
|
|
4
5
|
|
|
5
6
|
export function ContextPopover({
|
|
@@ -23,25 +24,33 @@ export function ContextPopover({
|
|
|
23
24
|
|
|
24
25
|
return (
|
|
25
26
|
<Popover.Root open={open} onOpenChange={onOpenChange}>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
27
|
+
{/* The tooltip trigger is a wrapper span, not the popover trigger
|
|
28
|
+
itself: `disabled` adds `pointer-events-none` to the button, so
|
|
29
|
+
only the span keeps hover — the icon's name stays discoverable
|
|
30
|
+
while the composer is disabled. */}
|
|
31
|
+
<Tooltip>
|
|
32
|
+
<TooltipTrigger render={<span className="stg:inline-flex" />}>
|
|
33
|
+
<Popover.Trigger
|
|
34
|
+
disabled={disabled}
|
|
35
|
+
aria-label={label}
|
|
36
|
+
className={cn(
|
|
37
|
+
"stg:inline-flex stg:h-8 stg:w-8 stg:items-center stg:justify-center stg:rounded-md stg:text-xs stg:transition-colors",
|
|
38
|
+
"stg:text-muted-foreground stg:hover:text-foreground stg:hover:bg-accent-hover",
|
|
39
|
+
"stg:disabled:pointer-events-none stg:disabled:opacity-50",
|
|
40
|
+
)}
|
|
41
|
+
>
|
|
42
|
+
<span className="stg:relative">
|
|
43
|
+
{icon}
|
|
44
|
+
{count > 0 && (
|
|
45
|
+
<span className="stg:absolute stg:-right-1.5 stg:-top-1.5 stg:flex stg:h-3.5 stg:min-w-3.5 stg:items-center stg:justify-center stg:rounded-full stg:bg-primary stg:px-0.5 stg:text-[0.5rem] stg:font-medium stg:leading-none stg:text-primary-foreground">
|
|
46
|
+
{count}
|
|
47
|
+
</span>
|
|
48
|
+
)}
|
|
41
49
|
</span>
|
|
42
|
-
|
|
43
|
-
</
|
|
44
|
-
|
|
50
|
+
</Popover.Trigger>
|
|
51
|
+
</TooltipTrigger>
|
|
52
|
+
<TooltipContent side="top">{label}</TooltipContent>
|
|
53
|
+
</Tooltip>
|
|
45
54
|
<Popover.Portal container={portalContainer}>
|
|
46
55
|
<Popover.Positioner sideOffset={8} align="start">
|
|
47
56
|
<Popover.Popup
|
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
resolveSystemEnvVarValues,
|
|
39
39
|
} from "../environment/systemEnvVars.js";
|
|
40
40
|
import { useRenderTracer } from "../internal/dev/index.js";
|
|
41
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from "../internal/tooltip.js";
|
|
41
42
|
import {
|
|
42
43
|
AgentIcon,
|
|
43
44
|
McpServerIcon,
|
|
@@ -333,6 +334,20 @@ export interface SessionComposerProps {
|
|
|
333
334
|
*/
|
|
334
335
|
readonly onAgentResolutionChange?: (resolution: AgentResolution | null) => void;
|
|
335
336
|
|
|
337
|
+
/**
|
|
338
|
+
* Called whenever the agent setup's error changes: an {@link Error} when
|
|
339
|
+
* resolution (or env submission) fails, `null` when the error clears.
|
|
340
|
+
*
|
|
341
|
+
* This is the ONLY way an embedder can observe a failed mount-time
|
|
342
|
+
* resolution of {@link SessionComposerProps.initialAgentRef}: the failure
|
|
343
|
+
* is captured internally and rendered inside the Configure popover's
|
|
344
|
+
* agent panel — a surface a locked, end-user-facing embed never opens.
|
|
345
|
+
* A parent that gates behavior on `onAgentResolutionChange` alone waits
|
|
346
|
+
* forever on a resolution that already failed; wire this to surface the
|
|
347
|
+
* reason instead.
|
|
348
|
+
*/
|
|
349
|
+
readonly onAgentSetupErrorChange?: (error: Error | null) => void;
|
|
350
|
+
|
|
336
351
|
/**
|
|
337
352
|
* Agent to auto-select when the composer mounts.
|
|
338
353
|
*
|
|
@@ -598,6 +613,7 @@ const SessionComposerInner = forwardRef<SessionComposerHandle, SessionComposerPr
|
|
|
598
613
|
agentRef,
|
|
599
614
|
onAgentRefChange,
|
|
600
615
|
onAgentResolutionChange,
|
|
616
|
+
onAgentSetupErrorChange,
|
|
601
617
|
initialAgentRef,
|
|
602
618
|
initialInstanceId,
|
|
603
619
|
isDefaultAgent = false,
|
|
@@ -718,6 +734,16 @@ const SessionComposerInner = forwardRef<SessionComposerHandle, SessionComposerPr
|
|
|
718
734
|
onAgentResolutionChange?.(agentSetup.state.resolution);
|
|
719
735
|
}, [agentSetup.state, onAgentResolutionChange]);
|
|
720
736
|
|
|
737
|
+
// The error's own bridge, beside the resolution's: the setup error is
|
|
738
|
+
// orthogonal to phase and is otherwise visible ONLY inside the Configure
|
|
739
|
+
// popover -- which a locked end-user embed never opens. Without this, a
|
|
740
|
+
// failed mount-time resolution of initialAgentRef is invisible to the
|
|
741
|
+
// parent (the resolution callback never fires on failure) and any parent
|
|
742
|
+
// gate waiting on it holds forever.
|
|
743
|
+
useEffect(() => {
|
|
744
|
+
onAgentSetupErrorChange?.(agentSetup.state.error ?? null);
|
|
745
|
+
}, [agentSetup.state.error, onAgentSetupErrorChange]);
|
|
746
|
+
|
|
721
747
|
// ---------------------------------------------------------------------------
|
|
722
748
|
// Attachments — file upload state machine
|
|
723
749
|
// ---------------------------------------------------------------------------
|
|
@@ -1522,15 +1548,21 @@ const SessionComposerInner = forwardRef<SessionComposerHandle, SessionComposerPr
|
|
|
1522
1548
|
Editing message
|
|
1523
1549
|
</span>
|
|
1524
1550
|
{onCancelEdit && (
|
|
1525
|
-
<
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1551
|
+
<Tooltip>
|
|
1552
|
+
<TooltipTrigger
|
|
1553
|
+
render={
|
|
1554
|
+
<button
|
|
1555
|
+
type="button"
|
|
1556
|
+
onClick={onCancelEdit}
|
|
1557
|
+
aria-label="Cancel editing"
|
|
1558
|
+
className="stg:rounded stg:p-0.5 stg:text-muted-foreground stg:transition-colors stg:hover:bg-accent stg:hover:text-foreground stg:focus-visible:outline-none stg:focus-visible:ring-1 stg:focus-visible:ring-ring"
|
|
1559
|
+
/>
|
|
1560
|
+
}
|
|
1561
|
+
>
|
|
1562
|
+
<XIcon />
|
|
1563
|
+
</TooltipTrigger>
|
|
1564
|
+
<TooltipContent side="top">Cancel editing (Esc)</TooltipContent>
|
|
1565
|
+
</Tooltip>
|
|
1534
1566
|
)}
|
|
1535
1567
|
</div>
|
|
1536
1568
|
)}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeAll, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import { render, cleanup } from "@testing-library/react";
|
|
3
|
+
import type { ReactNode } from "react";
|
|
4
|
+
import type { Stigmer } from "@stigmer/sdk";
|
|
5
|
+
import { StigmerContext } from "../../context";
|
|
6
|
+
import { ModelRegistryContext } from "../../models/ModelRegistryContext";
|
|
7
|
+
|
|
8
|
+
// Without a StigmerProvider the portal container is null, and Base UI's
|
|
9
|
+
// Portal renders nothing — pin it to document.body so popovers can mount.
|
|
10
|
+
vi.mock("../../portal-container", () => ({
|
|
11
|
+
useStigmerPortalContainer: () => document.body,
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
// Controllable agent-setup state — these tests drive the error slot directly
|
|
15
|
+
// instead of exercising the full resolution state machine (covered by
|
|
16
|
+
// useAgentSetup's own tests).
|
|
17
|
+
const mockAgentSetup = {
|
|
18
|
+
state: { status: "idle", error: null } as Record<string, unknown>,
|
|
19
|
+
resolveAgent: vi.fn(),
|
|
20
|
+
resolveToInstance: vi.fn(),
|
|
21
|
+
submitEnvVars: vi.fn(),
|
|
22
|
+
reset: vi.fn(),
|
|
23
|
+
};
|
|
24
|
+
vi.mock("../../agent/useAgentSetup", () => ({
|
|
25
|
+
useAgentSetup: () => mockAgentSetup,
|
|
26
|
+
}));
|
|
27
|
+
|
|
28
|
+
import { SessionComposer } from "../SessionComposer";
|
|
29
|
+
|
|
30
|
+
beforeAll(() => {
|
|
31
|
+
if (!("ResizeObserver" in globalThis)) {
|
|
32
|
+
(globalThis as unknown as { ResizeObserver: unknown }).ResizeObserver =
|
|
33
|
+
class {
|
|
34
|
+
observe() {}
|
|
35
|
+
unobserve() {}
|
|
36
|
+
disconnect() {}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
function createMinimalStigmerMock(): Stigmer {
|
|
42
|
+
return {
|
|
43
|
+
agentExecution: { uploadAttachment: vi.fn() },
|
|
44
|
+
environment: { getPersonal: vi.fn().mockResolvedValue(null) },
|
|
45
|
+
baseUrl: "http://localhost:8080",
|
|
46
|
+
getAuthCredential: vi.fn().mockResolvedValue("test-token"),
|
|
47
|
+
config: {
|
|
48
|
+
baseUrl: "http://localhost:8080",
|
|
49
|
+
getAccessToken: vi.fn().mockResolvedValue(""),
|
|
50
|
+
},
|
|
51
|
+
} as unknown as Stigmer;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function createWrapper(client: Stigmer) {
|
|
55
|
+
return function Wrapper({ children }: { children: ReactNode }) {
|
|
56
|
+
return (
|
|
57
|
+
<StigmerContext.Provider value={client}>
|
|
58
|
+
<ModelRegistryContext.Provider
|
|
59
|
+
value={{ models: [], isLoading: false, error: null, refetch: vi.fn() }}
|
|
60
|
+
>
|
|
61
|
+
{children}
|
|
62
|
+
</ModelRegistryContext.Provider>
|
|
63
|
+
</StigmerContext.Provider>
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function renderComposer(
|
|
69
|
+
props?: Partial<React.ComponentProps<typeof SessionComposer>>,
|
|
70
|
+
) {
|
|
71
|
+
const client = createMinimalStigmerMock();
|
|
72
|
+
return render(
|
|
73
|
+
<SessionComposer
|
|
74
|
+
onSubmit={vi.fn()}
|
|
75
|
+
org="acme"
|
|
76
|
+
agentRef={null}
|
|
77
|
+
onAgentRefChange={vi.fn()}
|
|
78
|
+
onSkillRefsChange={vi.fn()}
|
|
79
|
+
skillRefs={[]}
|
|
80
|
+
{...props}
|
|
81
|
+
/>,
|
|
82
|
+
{ wrapper: createWrapper(client) },
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
beforeEach(() => {
|
|
87
|
+
mockAgentSetup.state = { status: "idle", error: null };
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
afterEach(cleanup);
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* The agent setup error's OUTBOUND bridge. The error is otherwise rendered
|
|
94
|
+
* only inside the Configure popover's agent panel — which a locked,
|
|
95
|
+
* end-user-facing embed never opens — and onAgentResolutionChange fires only
|
|
96
|
+
* on success. Without this callback, a failed mount-time resolution of
|
|
97
|
+
* initialAgentRef is invisible to the parent, and any parent gate waiting on
|
|
98
|
+
* the resolution holds forever (the "dead launcher pane" class).
|
|
99
|
+
*/
|
|
100
|
+
describe("SessionComposer — onAgentSetupErrorChange", () => {
|
|
101
|
+
it("reports the setup error to the parent", () => {
|
|
102
|
+
const onError = vi.fn();
|
|
103
|
+
const failure = new Error("agent lookup timed out");
|
|
104
|
+
mockAgentSetup.state = { status: "idle", error: failure };
|
|
105
|
+
|
|
106
|
+
renderComposer({ onAgentSetupErrorChange: onError });
|
|
107
|
+
|
|
108
|
+
expect(onError).toHaveBeenCalledWith(failure);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("reports null when no error is present (and when it clears)", () => {
|
|
112
|
+
const onError = vi.fn();
|
|
113
|
+
renderComposer({ onAgentSetupErrorChange: onError });
|
|
114
|
+
|
|
115
|
+
expect(onError).toHaveBeenCalledWith(null);
|
|
116
|
+
expect(onError).not.toHaveBeenCalledWith(expect.any(Error));
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it("renders normally when the callback is not provided", () => {
|
|
120
|
+
mockAgentSetup.state = { status: "idle", error: new Error("boom") };
|
|
121
|
+
|
|
122
|
+
expect(() => renderComposer()).not.toThrow();
|
|
123
|
+
});
|
|
124
|
+
});
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeAll, beforeEach, afterEach } from "vitest";
|
|
2
|
-
import { render, screen, cleanup
|
|
2
|
+
import { render, screen, cleanup } from "@testing-library/react";
|
|
3
3
|
import type { ReactNode } from "react";
|
|
4
4
|
import type { Stigmer } from "@stigmer/sdk";
|
|
5
5
|
import { StigmerContext } from "../../context";
|
|
6
|
+
import { openMenu } from "../../__tests__/helpers/open-menu";
|
|
6
7
|
import { ModelRegistryContext } from "../../models/ModelRegistryContext";
|
|
7
8
|
|
|
8
9
|
// Controllable agent-setup state — lets these tests drive the lock × setup
|
|
@@ -79,17 +80,11 @@ function renderComposer(
|
|
|
79
80
|
);
|
|
80
81
|
}
|
|
81
82
|
|
|
82
|
-
/**
|
|
83
|
-
* Opens the composer's Configure menu and resolves once the portaled menu
|
|
84
|
-
* content mounts. Menu items render asynchronously in a portal, so a
|
|
85
|
-
* synchronous item query straight after the click races the mount (the
|
|
86
|
-
* openRowMenu idiom; see stigmer/stigmer#323).
|
|
87
|
-
*/
|
|
83
|
+
/** Opens the composer's Configure menu via the shared readiness-gated helper. */
|
|
88
84
|
async function openConfigureMenu() {
|
|
89
|
-
|
|
85
|
+
await openMenu(
|
|
90
86
|
screen.getByRole("button", { name: "Configure agent, tools, and skills" }),
|
|
91
87
|
);
|
|
92
|
-
await screen.findByRole("menu");
|
|
93
88
|
}
|
|
94
89
|
|
|
95
90
|
beforeEach(() => {
|
|
@@ -10,6 +10,7 @@ import { AttachmentImageLightbox } from "../attachment/AttachmentImageLightbox.j
|
|
|
10
10
|
import { formatFileSize } from "../attachment/attachment-utils.js";
|
|
11
11
|
import { UNSTYLED_BUTTON } from "../internal/form-primitives.js";
|
|
12
12
|
import { toError } from "../internal/toError.js";
|
|
13
|
+
import { TruncatedText } from "../internal/truncated-text.js";
|
|
13
14
|
import { useStigmer } from "../hooks.js";
|
|
14
15
|
import { useConversationMediaUrl } from "./useConversationMediaUrl.js";
|
|
15
16
|
|
|
@@ -191,7 +192,6 @@ function MediaDocumentChip({
|
|
|
191
192
|
return (
|
|
192
193
|
<div className={className}>
|
|
193
194
|
<span
|
|
194
|
-
title={name}
|
|
195
195
|
className="stg:inline-flex stg:max-w-[240px] stg:items-center stg:rounded-md stg:bg-muted-subtle stg:px-2 stg:py-1 stg:text-xs stg:text-foreground"
|
|
196
196
|
>
|
|
197
197
|
<button
|
|
@@ -206,7 +206,7 @@ function MediaDocumentChip({
|
|
|
206
206
|
)}
|
|
207
207
|
>
|
|
208
208
|
<FileGlyph />
|
|
209
|
-
<
|
|
209
|
+
<TruncatedText text={name} className="stg:min-w-0" />
|
|
210
210
|
{size !== null && (
|
|
211
211
|
<span className="stg:shrink-0 stg:text-muted-foreground">{size}</span>
|
|
212
212
|
)}
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
import { useAutoScroll } from "../internal/useAutoScroll.js";
|
|
20
20
|
import { ConversationMediaAttachment } from "./ConversationMediaAttachment.js";
|
|
21
21
|
import {
|
|
22
|
+
attemptExplanationOf,
|
|
22
23
|
authorKindOf,
|
|
23
24
|
inboundPlaceholderOf,
|
|
24
25
|
isInternalItem,
|
|
@@ -228,8 +229,10 @@ const TimelineItemRow = memo(function TimelineItemRow({
|
|
|
228
229
|
// relay, never pattern-matched; the numeric twin (receipt_error_code)
|
|
229
230
|
// stays off the surface as machine vocabulary. Gated exactly like
|
|
230
231
|
// ReceiptTicks' failed arm — attempt delivered AND receipt failed —
|
|
231
|
-
// so the attempt-axis explanation (
|
|
232
|
-
// structurally never leak in here
|
|
232
|
+
// so the attempt-axis explanation (attemptExplanationOf, cloud#262's
|
|
233
|
+
// slice) can structurally never leak in here: its gate requires
|
|
234
|
+
// attempt FAILED, this one attempt delivered, so at most one of the
|
|
235
|
+
// two explanations ever renders.
|
|
233
236
|
const receiptExplanation =
|
|
234
237
|
sendAttemptOf(item) === "delivered" &&
|
|
235
238
|
receiptOf(item) === "failed" &&
|
|
@@ -237,6 +240,15 @@ const TimelineItemRow = memo(function TimelineItemRow({
|
|
|
237
240
|
? item.receiptDetail
|
|
238
241
|
: null;
|
|
239
242
|
|
|
243
|
+
// The attempt axis's explanation (cloud#262, closing F-25), the same
|
|
244
|
+
// R-1 visible-text treatment as the receipt explanation and for the
|
|
245
|
+
// same reason: why a send failed is decision-bearing (a closed
|
|
246
|
+
// 24h-window refusal says "the customer must write first"; a deleted
|
|
247
|
+
// channel says there is nothing to retry). The words and the gate
|
|
248
|
+
// live in attemptExplanationOf — presentation vocabulary, never
|
|
249
|
+
// computed in the view.
|
|
250
|
+
const attemptExplanation = attemptExplanationOf(item);
|
|
251
|
+
|
|
240
252
|
return (
|
|
241
253
|
<li className={cn("stg:flex", isCustomer ? "stg:justify-start" : "stg:justify-end")}>
|
|
242
254
|
<div
|
|
@@ -274,6 +286,11 @@ const TimelineItemRow = memo(function TimelineItemRow({
|
|
|
274
286
|
{receiptExplanation}
|
|
275
287
|
</p>
|
|
276
288
|
)}
|
|
289
|
+
{attemptExplanation !== null && (
|
|
290
|
+
<p className="stg:mt-1 stg:break-words stg:text-xs stg:text-destructive">
|
|
291
|
+
{attemptExplanation}
|
|
292
|
+
</p>
|
|
293
|
+
)}
|
|
277
294
|
<ItemFooter item={item} />
|
|
278
295
|
</div>
|
|
279
296
|
</li>
|
|
@@ -10,7 +10,10 @@ import {
|
|
|
10
10
|
ConversationLane,
|
|
11
11
|
ConversationTimelineItemSchema,
|
|
12
12
|
} from "@stigmer/protos/ai/stigmer/agentic/agentchannel/v1/conversation_io_pb";
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
ChannelAttemptFailureKind,
|
|
15
|
+
ChannelDeliveryStatus,
|
|
16
|
+
} from "@stigmer/protos/ai/stigmer/agentic/agentchannel/v1/delivery_pb";
|
|
14
17
|
import { ChannelReceiptState } from "@stigmer/protos/ai/stigmer/agentic/agentchannel/v1/outbound_pb";
|
|
15
18
|
import { StigmerContext } from "../../context";
|
|
16
19
|
import { ConversationTimelineView } from "../ConversationTimelineView";
|
|
@@ -174,8 +177,9 @@ describe("ConversationTimelineView", () => {
|
|
|
174
177
|
text: "lost reply",
|
|
175
178
|
deliveryStatus: ChannelDeliveryStatus.failed,
|
|
176
179
|
// A malformed item carrying a detail on the wrong axis: the
|
|
177
|
-
// attempt-axis explanation
|
|
178
|
-
//
|
|
180
|
+
// attempt-axis explanation has its own field and gate
|
|
181
|
+
// (attemptExplanationOf, cloud#262), so a stray receipt
|
|
182
|
+
// detail still renders nothing here.
|
|
179
183
|
receiptDetail: "should never render",
|
|
180
184
|
}),
|
|
181
185
|
]}
|
|
@@ -185,6 +189,105 @@ describe("ConversationTimelineView", () => {
|
|
|
185
189
|
expect(screen.queryByText("should never render")).toBeNull();
|
|
186
190
|
});
|
|
187
191
|
|
|
192
|
+
it("shows a refused send's platform-authored explanation verbatim (cloud#262)", () => {
|
|
193
|
+
render(
|
|
194
|
+
<ConversationTimelineView
|
|
195
|
+
{...baseProps()}
|
|
196
|
+
items={[
|
|
197
|
+
item("ob:1", {
|
|
198
|
+
author: ConversationItemAuthor.author_teammate,
|
|
199
|
+
text: "Following up on your case.",
|
|
200
|
+
deliveryStatus: ChannelDeliveryStatus.failed,
|
|
201
|
+
attemptFailureKind: ChannelAttemptFailureKind.attempt_refused,
|
|
202
|
+
attemptDetail: "the recipient's 24-hour customer-service window is closed",
|
|
203
|
+
}),
|
|
204
|
+
]}
|
|
205
|
+
/>,
|
|
206
|
+
);
|
|
207
|
+
expect(screen.getByText("Not delivered")).toBeDefined();
|
|
208
|
+
expect(
|
|
209
|
+
screen.getByText("the recipient's 24-hour customer-service window is closed"),
|
|
210
|
+
).toBeDefined();
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it("shows a withdrawn send's structural fact verbatim (cloud#262)", () => {
|
|
214
|
+
render(
|
|
215
|
+
<ConversationTimelineView
|
|
216
|
+
{...baseProps()}
|
|
217
|
+
items={[
|
|
218
|
+
item("dl:1", {
|
|
219
|
+
author: ConversationItemAuthor.author_agent,
|
|
220
|
+
text: "the reply that never landed",
|
|
221
|
+
deliveryStatus: ChannelDeliveryStatus.failed,
|
|
222
|
+
attemptFailureKind: ChannelAttemptFailureKind.attempt_withdrawn,
|
|
223
|
+
attemptDetail: "channel deleted",
|
|
224
|
+
}),
|
|
225
|
+
]}
|
|
226
|
+
/>,
|
|
227
|
+
);
|
|
228
|
+
expect(screen.getByText("channel deleted")).toBeDefined();
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it("shows this surface's own generic copy for an errored send — the wire carries no detail (cloud#262)", () => {
|
|
232
|
+
render(
|
|
233
|
+
<ConversationTimelineView
|
|
234
|
+
{...baseProps()}
|
|
235
|
+
items={[
|
|
236
|
+
item("dl:1", {
|
|
237
|
+
author: ConversationItemAuthor.author_agent,
|
|
238
|
+
text: "lost reply",
|
|
239
|
+
deliveryStatus: ChannelDeliveryStatus.failed,
|
|
240
|
+
attemptFailureKind: ChannelAttemptFailureKind.attempt_errored,
|
|
241
|
+
// attemptDetail deliberately empty: the server's AttemptFailure
|
|
242
|
+
// construction keeps diagnostics off the wire entirely.
|
|
243
|
+
}),
|
|
244
|
+
]}
|
|
245
|
+
/>,
|
|
246
|
+
);
|
|
247
|
+
expect(screen.getByText("Not delivered")).toBeDefined();
|
|
248
|
+
expect(
|
|
249
|
+
screen.getByText("Delivery failed due to a technical problem on the platform's side."),
|
|
250
|
+
).toBeDefined();
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it("keeps the bare tick for a failure the platform never classified (pre-cloud#262 rows)", () => {
|
|
254
|
+
render(
|
|
255
|
+
<ConversationTimelineView
|
|
256
|
+
{...baseProps()}
|
|
257
|
+
items={[
|
|
258
|
+
item("ob:1", {
|
|
259
|
+
author: ConversationItemAuthor.author_teammate,
|
|
260
|
+
text: "an old failed send",
|
|
261
|
+
deliveryStatus: ChannelDeliveryStatus.failed,
|
|
262
|
+
}),
|
|
263
|
+
]}
|
|
264
|
+
/>,
|
|
265
|
+
);
|
|
266
|
+
expect(screen.getByText("Not delivered")).toBeDefined();
|
|
267
|
+
expect(screen.queryByText(/technical problem/)).toBeNull();
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
it("never shows the attempt explanation on a delivered item — the F-25 boundary's mirror", () => {
|
|
271
|
+
render(
|
|
272
|
+
<ConversationTimelineView
|
|
273
|
+
{...baseProps()}
|
|
274
|
+
items={[
|
|
275
|
+
item("ob:1", {
|
|
276
|
+
author: ConversationItemAuthor.author_teammate,
|
|
277
|
+
text: "a landed send",
|
|
278
|
+
deliveryStatus: ChannelDeliveryStatus.delivered,
|
|
279
|
+
// A malformed item carrying attempt copy on a success: the
|
|
280
|
+
// gate requires attempt FAILED, so nothing renders.
|
|
281
|
+
attemptFailureKind: ChannelAttemptFailureKind.attempt_refused,
|
|
282
|
+
attemptDetail: "should never render",
|
|
283
|
+
}),
|
|
284
|
+
]}
|
|
285
|
+
/>,
|
|
286
|
+
);
|
|
287
|
+
expect(screen.queryByText("should never render")).toBeNull();
|
|
288
|
+
expect(screen.queryByText("Not delivered")).toBeNull();
|
|
289
|
+
});
|
|
290
|
+
|
|
188
291
|
it("renders a dead-lettered send as exactly that", () => {
|
|
189
292
|
render(
|
|
190
293
|
<ConversationTimelineView
|
|
@@ -6,7 +6,10 @@ import {
|
|
|
6
6
|
ConversationLane,
|
|
7
7
|
type ConversationTimelineItem,
|
|
8
8
|
} from "@stigmer/protos/ai/stigmer/agentic/agentchannel/v1/conversation_io_pb";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
ChannelAttemptFailureKind,
|
|
11
|
+
ChannelDeliveryStatus,
|
|
12
|
+
} from "@stigmer/protos/ai/stigmer/agentic/agentchannel/v1/delivery_pb";
|
|
10
13
|
import { ChannelReceiptState } from "@stigmer/protos/ai/stigmer/agentic/agentchannel/v1/outbound_pb";
|
|
11
14
|
import type { ChannelProviderId } from "../channel/providers.js";
|
|
12
15
|
|
|
@@ -106,6 +109,54 @@ export function receiptOf(item: ConversationTimelineItem): ReceiptKind | null {
|
|
|
106
109
|
}
|
|
107
110
|
}
|
|
108
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Why a FAILED send attempt failed, in render vocabulary. `null` until
|
|
114
|
+
* the platform classifies (rows failed before the classification
|
|
115
|
+
* existed, and every non-failed item).
|
|
116
|
+
*
|
|
117
|
+
* The structured twin of {@link attemptExplanationOf}'s prose
|
|
118
|
+
* (cloud#262): a renderer that branches on the failure keys on this,
|
|
119
|
+
* never on the explanation's words.
|
|
120
|
+
*/
|
|
121
|
+
export type AttemptFailureKind = "refused" | "errored" | "withdrawn";
|
|
122
|
+
|
|
123
|
+
/** Map the wire attempt-failure kind onto the render vocabulary. */
|
|
124
|
+
export function attemptFailureOf(item: ConversationTimelineItem): AttemptFailureKind | null {
|
|
125
|
+
switch (item.attemptFailureKind) {
|
|
126
|
+
case ChannelAttemptFailureKind.attempt_refused:
|
|
127
|
+
return "refused";
|
|
128
|
+
case ChannelAttemptFailureKind.attempt_errored:
|
|
129
|
+
return "errored";
|
|
130
|
+
case ChannelAttemptFailureKind.attempt_withdrawn:
|
|
131
|
+
return "withdrawn";
|
|
132
|
+
default:
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* The visible explanation for a FAILED send attempt, or `null` when the
|
|
139
|
+
* item carries none to show (non-failed items, and rows failed before
|
|
140
|
+
* the platform classified failures).
|
|
141
|
+
*
|
|
142
|
+
* The attempt-axis sibling of the receipt explanation (cloud#262,
|
|
143
|
+
* closing F-25): `attempt_detail` is PLATFORM-authored thread-safe copy
|
|
144
|
+
* — the write side guarantees raw diagnostics never occupy it — so it
|
|
145
|
+
* renders verbatim when present (refusals and withdrawn sends). An
|
|
146
|
+
* `errored` failure deliberately carries no detail (its diagnostic is
|
|
147
|
+
* operator-only, in `last_error` server-side); the copy here is this
|
|
148
|
+
* surface's own generic for that arm, and it makes NO claim about
|
|
149
|
+
* attempt counts — the wire does not carry them, and `errored` covers
|
|
150
|
+
* first-try structural dead-letters as well as exhausted retries.
|
|
151
|
+
*/
|
|
152
|
+
export function attemptExplanationOf(item: ConversationTimelineItem): string | null {
|
|
153
|
+
if (sendAttemptOf(item) !== "failed") return null;
|
|
154
|
+
if (item.attemptDetail !== "") return item.attemptDetail;
|
|
155
|
+
return attemptFailureOf(item) === "errored"
|
|
156
|
+
? "Delivery failed due to a technical problem on the platform's side."
|
|
157
|
+
: null;
|
|
158
|
+
}
|
|
159
|
+
|
|
109
160
|
/**
|
|
110
161
|
* Placeholder copy for inbound items whose body the platform cannot
|
|
111
162
|
* render (`text` empty, `provider_message_type` names the kind) — the
|