@stigmer/react 3.12.3 → 3.12.5
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/agent/steps/IdentityStep.d.ts.map +1 -1
- package/agent/steps/IdentityStep.js +2 -1
- package/agent/steps/IdentityStep.js.map +1 -1
- package/agent-instance/AgentInstanceDetailPanel.d.ts.map +1 -1
- package/agent-instance/AgentInstanceDetailPanel.js +2 -1
- package/agent-instance/AgentInstanceDetailPanel.js.map +1 -1
- package/api-key/CreateApiKeyForm.d.ts.map +1 -1
- package/api-key/CreateApiKeyForm.js +2 -1
- package/api-key/CreateApiKeyForm.js.map +1 -1
- package/attachment/AttachmentChipList.js +16 -6
- package/attachment/AttachmentChipList.js.map +1 -1
- package/attachment/index.d.ts +1 -1
- package/attachment/index.d.ts.map +1 -1
- package/attachment/index.js.map +1 -1
- package/attachment/useAttachments.d.ts +51 -8
- package/attachment/useAttachments.d.ts.map +1 -1
- package/attachment/useAttachments.js +74 -3
- package/attachment/useAttachments.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/ConnectSlackDialog.d.ts.map +1 -1
- package/channel/ConnectSlackDialog.js +2 -1
- package/channel/ConnectSlackDialog.js.map +1 -1
- package/channel/connect/ServingAppSection.d.ts.map +1 -1
- package/channel/connect/ServingAppSection.js +2 -1
- package/channel/connect/ServingAppSection.js.map +1 -1
- package/channel-app/CreateChannelAppForm.d.ts.map +1 -1
- package/channel-app/CreateChannelAppForm.js +2 -1
- package/channel-app/CreateChannelAppForm.js.map +1 -1
- package/composer/SessionComposer.d.ts.map +1 -1
- package/composer/SessionComposer.js +17 -10
- package/composer/SessionComposer.js.map +1 -1
- package/conversation/ConversationComposer.d.ts +19 -3
- package/conversation/ConversationComposer.d.ts.map +1 -1
- package/conversation/ConversationComposer.js +4 -4
- package/conversation/ConversationComposer.js.map +1 -1
- package/conversation/ConversationListPane.d.ts.map +1 -1
- package/conversation/ConversationListPane.js +2 -1
- package/conversation/ConversationListPane.js.map +1 -1
- package/conversation/ConversationTemplatePickerDialog.d.ts +63 -0
- package/conversation/ConversationTemplatePickerDialog.d.ts.map +1 -0
- package/conversation/ConversationTemplatePickerDialog.js +151 -0
- package/conversation/ConversationTemplatePickerDialog.js.map +1 -0
- package/conversation/ConversationTimelineView.d.ts.map +1 -1
- package/conversation/ConversationTimelineView.js +2 -1
- package/conversation/ConversationTimelineView.js.map +1 -1
- package/conversation/ConversationsWorkbench.d.ts.map +1 -1
- package/conversation/ConversationsWorkbench.js +16 -5
- package/conversation/ConversationsWorkbench.js.map +1 -1
- package/conversation/index.d.ts +3 -1
- package/conversation/index.d.ts.map +1 -1
- package/conversation/index.js +1 -0
- package/conversation/index.js.map +1 -1
- package/conversation/useConversationParticipation.d.ts +41 -4
- package/conversation/useConversationParticipation.d.ts.map +1 -1
- package/conversation/useConversationParticipation.js +13 -2
- package/conversation/useConversationParticipation.js.map +1 -1
- package/cursor-accounts/CursorAccountsConsole.d.ts.map +1 -1
- package/cursor-accounts/CursorAccountsConsole.js +2 -1
- package/cursor-accounts/CursorAccountsConsole.js.map +1 -1
- package/cursor-accounts/MemberKeysPanel.d.ts.map +1 -1
- package/cursor-accounts/MemberKeysPanel.js +2 -1
- package/cursor-accounts/MemberKeysPanel.js.map +1 -1
- package/dashboard/DashboardFailedRuns.d.ts.map +1 -1
- package/dashboard/DashboardFailedRuns.js +2 -1
- package/dashboard/DashboardFailedRuns.js.map +1 -1
- package/dependency-graph/DependencyGraph.d.ts.map +1 -1
- package/dependency-graph/DependencyGraph.js +2 -1
- package/dependency-graph/DependencyGraph.js.map +1 -1
- package/dependency-graph/DependencyTreeNode.d.ts.map +1 -1
- package/dependency-graph/DependencyTreeNode.js +2 -1
- package/dependency-graph/DependencyTreeNode.js.map +1 -1
- package/environment/EnvironmentPicker.d.ts.map +1 -1
- package/environment/EnvironmentPicker.js +2 -1
- package/environment/EnvironmentPicker.js.map +1 -1
- package/error/SecretFlowErrorGuide.d.ts.map +1 -1
- package/error/SecretFlowErrorGuide.js +2 -1
- package/error/SecretFlowErrorGuide.js.map +1 -1
- package/execution/ArtifactContentBody.d.ts.map +1 -1
- package/execution/ArtifactContentBody.js +2 -1
- package/execution/ArtifactContentBody.js.map +1 -1
- package/execution/ArtifactsWidget.d.ts.map +1 -1
- package/execution/ArtifactsWidget.js +2 -1
- package/execution/ArtifactsWidget.js.map +1 -1
- package/execution/FileChangeProgressBar.d.ts.map +1 -1
- package/execution/FileChangeProgressBar.js +2 -1
- package/execution/FileChangeProgressBar.js.map +1 -1
- package/execution/TodoList.d.ts.map +1 -1
- package/execution/TodoList.js +2 -1
- package/execution/TodoList.js.map +1 -1
- package/execution/WriteBacksWidget.d.ts.map +1 -1
- package/execution/WriteBacksWidget.js +2 -1
- package/execution/WriteBacksWidget.js.map +1 -1
- package/execution/tool-categories.d.ts +5 -22
- package/execution/tool-categories.d.ts.map +1 -1
- package/execution/tool-categories.js +8 -38
- package/execution/tool-categories.js.map +1 -1
- package/iam-policy/PeopleWithAccess.d.ts.map +1 -1
- package/iam-policy/PeopleWithAccess.js +2 -1
- package/iam-policy/PeopleWithAccess.js.map +1 -1
- package/iam-policy/PrincipalPicker.d.ts.map +1 -1
- package/iam-policy/PrincipalPicker.js +2 -1
- package/iam-policy/PrincipalPicker.js.map +1 -1
- package/iam-policy/RoleSelector.d.ts.map +1 -1
- package/iam-policy/RoleSelector.js +2 -1
- package/iam-policy/RoleSelector.js.map +1 -1
- package/identity-account/AccountPreferencesPanel.d.ts +35 -0
- package/identity-account/AccountPreferencesPanel.d.ts.map +1 -0
- package/identity-account/AccountPreferencesPanel.js +187 -0
- package/identity-account/AccountPreferencesPanel.js.map +1 -0
- package/identity-account/index.d.ts +8 -0
- package/identity-account/index.d.ts.map +1 -1
- package/identity-account/index.js +4 -0
- package/identity-account/index.js.map +1 -1
- package/identity-account/useAccountExecutionDefaults.d.ts +36 -0
- package/identity-account/useAccountExecutionDefaults.d.ts.map +1 -0
- package/identity-account/useAccountExecutionDefaults.js +46 -0
- package/identity-account/useAccountExecutionDefaults.js.map +1 -0
- package/identity-account/useMyIdentityAccount.d.ts +55 -0
- package/identity-account/useMyIdentityAccount.d.ts.map +1 -0
- package/identity-account/useMyIdentityAccount.js +37 -0
- package/identity-account/useMyIdentityAccount.js.map +1 -0
- package/identity-account/useUpdateIdentityAccount.d.ts +42 -0
- package/identity-account/useUpdateIdentityAccount.d.ts.map +1 -0
- package/identity-account/useUpdateIdentityAccount.js +53 -0
- package/identity-account/useUpdateIdentityAccount.js.map +1 -0
- package/identity-provider/CreateIdentityProviderForm.d.ts.map +1 -1
- package/identity-provider/CreateIdentityProviderForm.js +2 -1
- package/identity-provider/CreateIdentityProviderForm.js.map +1 -1
- package/identity-provider/IdentityProviderDetailPanel.d.ts.map +1 -1
- package/identity-provider/IdentityProviderDetailPanel.js +2 -1
- package/identity-provider/IdentityProviderDetailPanel.js.map +1 -1
- package/identity-provider/IdentityProviderWizard.d.ts.map +1 -1
- package/identity-provider/IdentityProviderWizard.js +2 -1
- package/identity-provider/IdentityProviderWizard.js.map +1 -1
- package/index.d.ts +14 -10
- package/index.d.ts.map +1 -1
- package/index.js +11 -5
- package/index.js.map +1 -1
- package/internal/StandingContextField.d.ts +37 -0
- package/internal/StandingContextField.d.ts.map +1 -0
- package/internal/StandingContextField.js +24 -0
- package/internal/StandingContextField.js.map +1 -0
- package/internal/element-resets.d.ts +17 -0
- package/internal/element-resets.d.ts.map +1 -0
- package/internal/element-resets.js +32 -0
- package/internal/element-resets.js.map +1 -0
- package/internal/file-tree/FileTreeNode.d.ts.map +1 -1
- package/internal/file-tree/FileTreeNode.js +2 -1
- package/internal/file-tree/FileTreeNode.js.map +1 -1
- package/internal/markdown-components.d.ts +7 -0
- package/internal/markdown-components.d.ts.map +1 -1
- package/internal/markdown-components.js +15 -5
- package/internal/markdown-components.js.map +1 -1
- package/invitation/InvitationManager.d.ts.map +1 -1
- package/invitation/InvitationManager.js +2 -1
- package/invitation/InvitationManager.js.map +1 -1
- package/library/InstanceVisibilitySelector.d.ts.map +1 -1
- package/library/InstanceVisibilitySelector.js +9 -2
- package/library/InstanceVisibilitySelector.js.map +1 -1
- package/library/ResourceVisibilityControl.d.ts +13 -3
- package/library/ResourceVisibilityControl.d.ts.map +1 -1
- package/library/ResourceVisibilityControl.js +33 -5
- package/library/ResourceVisibilityControl.js.map +1 -1
- package/library/VisibilityOptionRow.d.ts +6 -0
- package/library/VisibilityOptionRow.d.ts.map +1 -1
- package/library/VisibilityOptionRow.js +11 -1
- package/library/VisibilityOptionRow.js.map +1 -1
- package/library/VisibilitySelector.d.ts.map +1 -1
- package/library/VisibilitySelector.js +14 -2
- package/library/VisibilitySelector.js.map +1 -1
- package/library/index.d.ts +4 -2
- package/library/index.d.ts.map +1 -1
- package/library/index.js +2 -1
- package/library/index.js.map +1 -1
- package/library/useCanSetPublicVisibility.d.ts +30 -0
- package/library/useCanSetPublicVisibility.d.ts.map +1 -0
- package/library/useCanSetPublicVisibility.js +41 -0
- package/library/useCanSetPublicVisibility.js.map +1 -0
- package/library/visibilityLevels.d.ts +32 -1
- package/library/visibilityLevels.d.ts.map +1 -1
- package/library/visibilityLevels.js +34 -14
- package/library/visibilityLevels.js.map +1 -1
- package/manifest/ApplyManifestDialog.d.ts.map +1 -1
- package/manifest/ApplyManifestDialog.js +2 -1
- package/manifest/ApplyManifestDialog.js.map +1 -1
- package/mcp-server/steps/IdentityTransportStep.d.ts.map +1 -1
- package/mcp-server/steps/IdentityTransportStep.js +2 -1
- package/mcp-server/steps/IdentityTransportStep.js.map +1 -1
- package/mcp-server/useMcpServerConnect.d.ts +8 -5
- package/mcp-server/useMcpServerConnect.d.ts.map +1 -1
- package/mcp-server/useMcpServerConnect.js +2 -1
- package/mcp-server/useMcpServerConnect.js.map +1 -1
- package/mcp-server/useMcpServerOAuthConnect.d.ts.map +1 -1
- package/mcp-server/useMcpServerOAuthConnect.js +7 -2
- package/mcp-server/useMcpServerOAuthConnect.js.map +1 -1
- package/oauth-app/CreateOAuthAppForm.d.ts +2 -2
- package/oauth-app/CreateOAuthAppForm.d.ts.map +1 -1
- package/oauth-app/CreateOAuthAppForm.js +13 -4
- package/oauth-app/CreateOAuthAppForm.js.map +1 -1
- package/oauth-app/OAuthAppDetailPanel.d.ts.map +1 -1
- package/oauth-app/OAuthAppDetailPanel.js +32 -5
- package/oauth-app/OAuthAppDetailPanel.js.map +1 -1
- package/organization/OrgPreferencesPanel.d.ts +32 -0
- package/organization/OrgPreferencesPanel.d.ts.map +1 -0
- package/organization/OrgPreferencesPanel.js +90 -0
- package/organization/OrgPreferencesPanel.js.map +1 -0
- package/organization/OrgProfilePanel.d.ts.map +1 -1
- package/organization/OrgProfilePanel.js +5 -4
- package/organization/OrgProfilePanel.js.map +1 -1
- package/organization/index.d.ts +2 -0
- package/organization/index.d.ts.map +1 -1
- package/organization/index.js +1 -0
- package/organization/index.js.map +1 -1
- package/package.json +4 -4
- package/platform-client/CreatePlatformClientForm.d.ts.map +1 -1
- package/platform-client/CreatePlatformClientForm.js +2 -1
- package/platform-client/CreatePlatformClientForm.js.map +1 -1
- package/platform-client/PlatformClientDetailPanel.d.ts.map +1 -1
- package/platform-client/PlatformClientDetailPanel.js +2 -1
- package/platform-client/PlatformClientDetailPanel.js.map +1 -1
- package/pricing-governance/BaselineEditor.d.ts.map +1 -1
- package/pricing-governance/BaselineEditor.js +2 -1
- package/pricing-governance/BaselineEditor.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/provider-standing/ProviderStandingAccessNotice.d.ts +11 -0
- package/provider-standing/ProviderStandingAccessNotice.d.ts.map +1 -0
- package/provider-standing/ProviderStandingAccessNotice.js +14 -0
- package/provider-standing/ProviderStandingAccessNotice.js.map +1 -0
- package/provider-standing/ProviderStandingConsole.d.ts +24 -0
- package/provider-standing/ProviderStandingConsole.d.ts.map +1 -0
- package/provider-standing/ProviderStandingConsole.js +98 -0
- package/provider-standing/ProviderStandingConsole.js.map +1 -0
- package/provider-standing/index.d.ts +6 -0
- package/provider-standing/index.d.ts.map +1 -0
- package/provider-standing/index.js +6 -0
- package/provider-standing/index.js.map +1 -0
- package/provider-standing/useProviderStanding.d.ts +34 -0
- package/provider-standing/useProviderStanding.d.ts.map +1 -0
- package/provider-standing/useProviderStanding.js +26 -0
- package/provider-standing/useProviderStanding.js.map +1 -0
- package/provider.d.ts +12 -0
- package/provider.d.ts.map +1 -1
- package/provider.js +12 -0
- package/provider.js.map +1 -1
- package/resource-creation/StepIndicator.d.ts.map +1 -1
- package/resource-creation/StepIndicator.js +2 -1
- package/resource-creation/StepIndicator.js.map +1 -1
- package/schedule/ScheduleDetailView.d.ts.map +1 -1
- package/schedule/ScheduleDetailView.js +3 -2
- package/schedule/ScheduleDetailView.js.map +1 -1
- package/schedule/ScheduleRunsTable.d.ts.map +1 -1
- package/schedule/ScheduleRunsTable.js +2 -1
- package/schedule/ScheduleRunsTable.js.map +1 -1
- package/session/NewSessionViewer.d.ts +10 -1
- package/session/NewSessionViewer.d.ts.map +1 -1
- package/session/NewSessionViewer.js +2 -1
- package/session/NewSessionViewer.js.map +1 -1
- package/session/facets/ArtifactsTab.d.ts.map +1 -1
- package/session/facets/ArtifactsTab.js +2 -1
- package/session/facets/ArtifactsTab.js.map +1 -1
- package/session/facets/ChangesTab.d.ts.map +1 -1
- package/session/facets/ChangesTab.js +2 -1
- package/session/facets/ChangesTab.js.map +1 -1
- package/session/facets/UsageTab.d.ts +10 -3
- package/session/facets/UsageTab.d.ts.map +1 -1
- package/session/facets/UsageTab.js +42 -6
- package/session/facets/UsageTab.js.map +1 -1
- package/session/index.d.ts +1 -1
- package/session/index.d.ts.map +1 -1
- package/session/index.js.map +1 -1
- package/session/useNewSessionFlow.d.ts +27 -1
- package/session/useNewSessionFlow.d.ts.map +1 -1
- package/session/useNewSessionFlow.js +45 -8
- package/session/useNewSessionFlow.js.map +1 -1
- package/session/useSessionUsage.d.ts +25 -0
- package/session/useSessionUsage.d.ts.map +1 -1
- package/session/useSessionUsage.js +11 -0
- package/session/useSessionUsage.js.map +1 -1
- package/settings/AccountPreferencesSection.d.ts +3 -0
- package/settings/AccountPreferencesSection.d.ts.map +1 -0
- package/settings/AccountPreferencesSection.js +10 -0
- package/settings/AccountPreferencesSection.js.map +1 -0
- package/settings/OrgPreferencesSection.d.ts +3 -0
- package/settings/OrgPreferencesSection.d.ts.map +1 -0
- package/settings/OrgPreferencesSection.js +13 -0
- package/settings/OrgPreferencesSection.js.map +1 -0
- package/settings/index.d.ts +2 -0
- package/settings/index.d.ts.map +1 -1
- package/settings/index.js +2 -0
- package/settings/index.js.map +1 -1
- package/settings/settings-nav.d.ts.map +1 -1
- package/settings/settings-nav.js +23 -1
- package/settings/settings-nav.js.map +1 -1
- package/settings/useSettingsNavGroups.d.ts.map +1 -1
- package/settings/useSettingsNavGroups.js +4 -1
- package/settings/useSettingsNavGroups.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/sidebar/WorkspaceSidebar.d.ts.map +1 -1
- package/sidebar/WorkspaceSidebar.js +2 -1
- package/sidebar/WorkspaceSidebar.js.map +1 -1
- package/skill/SkillFileBrowser.d.ts.map +1 -1
- package/skill/SkillFileBrowser.js +2 -1
- package/skill/SkillFileBrowser.js.map +1 -1
- package/skill/internal/fetchAndUnpackArtifact.d.ts +1 -1
- package/skill/internal/fetchAndUnpackArtifact.d.ts.map +1 -1
- package/skill/internal/fetchAndUnpackArtifact.js +47 -3
- package/skill/internal/fetchAndUnpackArtifact.js.map +1 -1
- package/skill/useSkillDiff.d.ts.map +1 -1
- package/skill/useSkillDiff.js +7 -1
- package/skill/useSkillDiff.js.map +1 -1
- package/skill/useSkillUpload.d.ts.map +1 -1
- package/skill/useSkillUpload.js +22 -4
- package/skill/useSkillUpload.js.map +1 -1
- package/src/__tests__/bare-host-resets.layout.test.tsx +184 -0
- package/src/agent/steps/IdentityStep.tsx +2 -1
- package/src/agent-instance/AgentInstanceDetailPanel.tsx +2 -1
- package/src/api-key/CreateApiKeyForm.tsx +2 -1
- package/src/attachment/AttachmentChipList.tsx +19 -8
- package/src/attachment/__tests__/AttachmentChipList.test.tsx +12 -0
- package/src/attachment/__tests__/useAttachments.test.ts +293 -0
- package/src/attachment/index.ts +1 -0
- package/src/attachment/useAttachments.ts +143 -11
- package/src/channel/ChannelConversationsDialog.tsx +2 -1
- package/src/channel/ChannelTemplatesDialog.tsx +2 -1
- package/src/channel/ConnectSlackDialog.tsx +2 -1
- package/src/channel/connect/ServingAppSection.tsx +2 -1
- package/src/channel-app/CreateChannelAppForm.tsx +2 -1
- package/src/composer/SessionComposer.tsx +23 -14
- package/src/conversation/ConversationComposer.tsx +38 -4
- package/src/conversation/ConversationListPane.tsx +2 -5
- package/src/conversation/ConversationTemplatePickerDialog.tsx +441 -0
- package/src/conversation/ConversationTimelineView.tsx +2 -1
- package/src/conversation/ConversationsWorkbench.tsx +40 -4
- package/src/conversation/__tests__/ConversationComposer.test.tsx +56 -1
- package/src/conversation/__tests__/ConversationTemplatePickerDialog.test.tsx +224 -0
- package/src/conversation/__tests__/useConversationParticipation.test.tsx +45 -4
- package/src/conversation/index.ts +4 -0
- package/src/conversation/useConversationParticipation.ts +58 -6
- package/src/cursor-accounts/CursorAccountsConsole.tsx +2 -1
- package/src/cursor-accounts/MemberKeysPanel.tsx +2 -1
- package/src/dashboard/DashboardFailedRuns.tsx +2 -1
- package/src/dependency-graph/DependencyGraph.tsx +2 -1
- package/src/dependency-graph/DependencyTreeNode.tsx +2 -1
- package/src/environment/EnvironmentPicker.tsx +2 -1
- package/src/error/SecretFlowErrorGuide.tsx +3 -2
- package/src/execution/ArtifactContentBody.tsx +2 -1
- package/src/execution/ArtifactsWidget.tsx +2 -1
- package/src/execution/FileChangeProgressBar.tsx +2 -1
- package/src/execution/TodoList.tsx +2 -1
- package/src/execution/WriteBacksWidget.tsx +2 -1
- package/src/execution/tool-categories.ts +17 -41
- package/src/iam-policy/PeopleWithAccess.tsx +2 -1
- package/src/iam-policy/PrincipalPicker.tsx +2 -0
- package/src/iam-policy/RoleSelector.tsx +2 -1
- package/src/identity-account/AccountPreferencesPanel.tsx +446 -0
- package/src/identity-account/__tests__/AccountPreferencesPanel.test.tsx +233 -0
- package/src/identity-account/__tests__/useAccountExecutionDefaults.test.tsx +116 -0
- package/src/identity-account/__tests__/useMyIdentityAccount.test.tsx +121 -0
- package/src/identity-account/index.ts +11 -0
- package/src/identity-account/useAccountExecutionDefaults.ts +63 -0
- package/src/identity-account/useMyIdentityAccount.ts +75 -0
- package/src/identity-account/useUpdateIdentityAccount.ts +73 -0
- package/src/identity-provider/CreateIdentityProviderForm.tsx +2 -1
- package/src/identity-provider/IdentityProviderDetailPanel.tsx +2 -1
- package/src/identity-provider/IdentityProviderWizard.tsx +2 -1
- package/src/index.ts +37 -2
- package/src/internal/StandingContextField.tsx +92 -0
- package/src/internal/element-resets.ts +33 -0
- package/src/internal/file-tree/FileTreeNode.tsx +2 -1
- package/src/internal/markdown-components.tsx +15 -5
- package/src/invitation/InvitationManager.tsx +3 -2
- package/src/library/InstanceVisibilitySelector.tsx +9 -2
- package/src/library/ResourceVisibilityControl.tsx +46 -13
- package/src/library/VisibilityOptionRow.tsx +28 -6
- package/src/library/VisibilitySelector.tsx +14 -2
- package/src/library/__tests__/VisibilitySelector.test.tsx +48 -1
- package/src/library/__tests__/visibilityLevels.test.ts +67 -1
- package/src/library/index.ts +6 -1
- package/src/library/useCanSetPublicVisibility.ts +56 -0
- package/src/library/visibilityLevels.ts +65 -14
- package/src/manifest/ApplyManifestDialog.tsx +2 -1
- package/src/mcp-server/__tests__/useMcpServerConnect.asyncLane.test.tsx +117 -0
- package/src/mcp-server/steps/IdentityTransportStep.tsx +3 -2
- package/src/mcp-server/useMcpServerConnect.ts +9 -6
- package/src/mcp-server/useMcpServerOAuthConnect.ts +7 -2
- package/src/oauth-app/CreateOAuthAppForm.tsx +58 -3
- package/src/oauth-app/OAuthAppDetailPanel.tsx +84 -3
- package/src/organization/OrgPreferencesPanel.tsx +221 -0
- package/src/organization/OrgProfilePanel.tsx +5 -4
- package/src/organization/__tests__/OrgPreferencesPanel.test.tsx +145 -0
- package/src/organization/__tests__/OrgProfilePanel.test.tsx +108 -0
- package/src/organization/index.ts +2 -0
- package/src/platform-client/CreatePlatformClientForm.tsx +4 -3
- package/src/platform-client/PlatformClientDetailPanel.tsx +4 -3
- package/src/pricing-governance/BaselineEditor.tsx +3 -2
- package/src/pricing-governance/PricingGovernanceConsole.tsx +2 -1
- package/src/provider-standing/ProviderStandingAccessNotice.tsx +36 -0
- package/src/provider-standing/ProviderStandingConsole.tsx +216 -0
- package/src/provider-standing/__tests__/ProviderStandingConsole.test.tsx +143 -0
- package/src/provider-standing/index.ts +8 -0
- package/src/provider-standing/useProviderStanding.ts +50 -0
- package/src/provider.tsx +12 -0
- package/src/resource-creation/StepIndicator.tsx +2 -1
- package/src/schedule/ScheduleDetailView.tsx +3 -2
- package/src/schedule/ScheduleRunsTable.tsx +2 -1
- package/src/session/NewSessionViewer.tsx +12 -0
- package/src/session/__tests__/UsageTab.test.tsx +136 -0
- package/src/session/__tests__/useNewSessionFlow.test.tsx +151 -0
- package/src/session/__tests__/useSessionUsage.test.ts +19 -0
- package/src/session/facets/ArtifactsTab.tsx +2 -1
- package/src/session/facets/ChangesTab.tsx +2 -1
- package/src/session/facets/UsageTab.tsx +98 -6
- package/src/session/index.ts +1 -0
- package/src/session/useNewSessionFlow.ts +76 -9
- package/src/session/useSessionUsage.ts +37 -0
- package/src/settings/AccountPreferencesSection.tsx +25 -0
- package/src/settings/OrgPreferencesSection.tsx +35 -0
- package/src/settings/__tests__/settings-nav.test.ts +27 -0
- package/src/settings/__tests__/useSettingsNavGroups.test.tsx +11 -1
- package/src/settings/index.ts +2 -0
- package/src/settings/settings-nav.ts +25 -0
- package/src/settings/useSettingsNavGroups.ts +8 -1
- package/src/sharing/ShareAgentDialog.tsx +2 -1
- package/src/sidebar/WorkspaceSidebar.tsx +2 -1
- package/src/skill/SkillFileBrowser.tsx +2 -1
- package/src/skill/__tests__/SkillFileBrowser.test.tsx +10 -2
- package/src/skill/__tests__/fetchAndUnpackArtifact.test.ts +90 -0
- package/src/skill/__tests__/useSkillUpload.test.ts +69 -0
- package/src/skill/internal/fetchAndUnpackArtifact.ts +54 -4
- package/src/skill/useSkillDiff.ts +7 -1
- package/src/skill/useSkillUpload.ts +25 -6
- package/src/workflow/ApprovalFormBuilder.tsx +5 -27
- package/src/workflow/FailedRunsWidget.tsx +2 -1
- package/src/workflow/PendingApprovalsWidget.tsx +2 -1
- package/src/workflow/facets/WorkflowArtifactsTab.tsx +2 -1
- package/src/workflow/facets/WorkflowUsageTab.tsx +2 -1
- package/src/workflow/inspector/WorkflowSummaryPanel.tsx +2 -1
- package/src/workflow/inspector/tabs/BranchesTab.tsx +2 -1
- package/src/workflow/inspector/tabs/IterationTab.tsx +2 -1
- package/src/workflow/instance/WorkflowInstanceDetailPanel.tsx +2 -1
- package/src/workspace/ExplorerTree.tsx +2 -1
- package/src/workspace/WorkspaceContentSearch.tsx +2 -1
- package/src/workspace/WorkspaceFileSearch.tsx +2 -1
- package/src/workspace/WorkspaceSummary.tsx +2 -1
- package/styles.css +1 -1
- package/workflow/ApprovalFormBuilder.d.ts.map +1 -1
- package/workflow/ApprovalFormBuilder.js +8 -5
- package/workflow/ApprovalFormBuilder.js.map +1 -1
- package/workflow/FailedRunsWidget.d.ts.map +1 -1
- package/workflow/FailedRunsWidget.js +2 -1
- package/workflow/FailedRunsWidget.js.map +1 -1
- package/workflow/PendingApprovalsWidget.d.ts.map +1 -1
- package/workflow/PendingApprovalsWidget.js +2 -1
- package/workflow/PendingApprovalsWidget.js.map +1 -1
- package/workflow/facets/WorkflowArtifactsTab.d.ts.map +1 -1
- package/workflow/facets/WorkflowArtifactsTab.js +2 -1
- package/workflow/facets/WorkflowArtifactsTab.js.map +1 -1
- package/workflow/facets/WorkflowUsageTab.d.ts.map +1 -1
- package/workflow/facets/WorkflowUsageTab.js +2 -1
- package/workflow/facets/WorkflowUsageTab.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 +2 -1
- package/workflow/inspector/tabs/BranchesTab.js.map +1 -1
- package/workflow/inspector/tabs/IterationTab.d.ts.map +1 -1
- package/workflow/inspector/tabs/IterationTab.js +2 -1
- package/workflow/inspector/tabs/IterationTab.js.map +1 -1
- package/workflow/instance/WorkflowInstanceDetailPanel.d.ts.map +1 -1
- package/workflow/instance/WorkflowInstanceDetailPanel.js +2 -1
- package/workflow/instance/WorkflowInstanceDetailPanel.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/WorkspaceContentSearch.d.ts.map +1 -1
- package/workspace/WorkspaceContentSearch.js +2 -1
- package/workspace/WorkspaceContentSearch.js.map +1 -1
- package/workspace/WorkspaceFileSearch.d.ts.map +1 -1
- package/workspace/WorkspaceFileSearch.js +2 -1
- package/workspace/WorkspaceFileSearch.js.map +1 -1
- package/workspace/WorkspaceSummary.d.ts.map +1 -1
- package/workspace/WorkspaceSummary.js +2 -1
- package/workspace/WorkspaceSummary.js.map +1 -1
|
@@ -53,6 +53,12 @@ export interface VisibilityOptionRowProps {
|
|
|
53
53
|
* label, one-line description, and a check when current. Shared by the
|
|
54
54
|
* {@link VisibilitySelector} popover and its create-mode inline list so
|
|
55
55
|
* option presentation has exactly one source.
|
|
56
|
+
*
|
|
57
|
+
* A level carrying {@link VisibilityLevelOption.lockedReason} renders
|
|
58
|
+
* non-interactive with a lock affordance and the reason as its detail line
|
|
59
|
+
* — the level stays discoverable (the reason names the path forward)
|
|
60
|
+
* without being selectable. The locked row keeps its normal opacity: it is
|
|
61
|
+
* informative, not in a transient disabled state.
|
|
56
62
|
*/
|
|
57
63
|
export const VisibilityOptionRow = forwardRef<
|
|
58
64
|
HTMLButtonElement,
|
|
@@ -71,6 +77,7 @@ export const VisibilityOptionRow = forwardRef<
|
|
|
71
77
|
},
|
|
72
78
|
ref,
|
|
73
79
|
) {
|
|
80
|
+
const locked = option.lockedReason !== undefined;
|
|
74
81
|
const selectionAttr =
|
|
75
82
|
role === "radio"
|
|
76
83
|
? { "aria-checked": isSelected }
|
|
@@ -82,16 +89,20 @@ export const VisibilityOptionRow = forwardRef<
|
|
|
82
89
|
type="button"
|
|
83
90
|
role={role}
|
|
84
91
|
{...selectionAttr}
|
|
92
|
+
aria-disabled={locked || undefined}
|
|
85
93
|
tabIndex={tabIndex}
|
|
86
|
-
disabled={disabled}
|
|
94
|
+
disabled={disabled || locked}
|
|
87
95
|
onClick={onSelect}
|
|
88
96
|
onMouseEnter={onMouseEnter}
|
|
89
97
|
onKeyDown={onKeyDown}
|
|
90
98
|
className={cn(
|
|
91
99
|
"stg:flex stg:w-full stg:items-start stg:gap-2 stg:rounded-md stg:px-2.5 stg:py-2 stg:text-left stg:transition-colors",
|
|
92
100
|
"stg:focus-visible:outline-none stg:focus-visible:ring-2 stg:focus-visible:ring-ring",
|
|
93
|
-
|
|
94
|
-
|
|
101
|
+
locked
|
|
102
|
+
? "stg:disabled:pointer-events-none stg:cursor-default"
|
|
103
|
+
: "stg:disabled:pointer-events-none stg:disabled:opacity-50",
|
|
104
|
+
!locked &&
|
|
105
|
+
(isHighlighted ? "stg:bg-accent stg:text-foreground" : "stg:hover:bg-accent-hover"),
|
|
95
106
|
)}
|
|
96
107
|
>
|
|
97
108
|
<VisibilityIcon
|
|
@@ -99,14 +110,25 @@ export const VisibilityOptionRow = forwardRef<
|
|
|
99
110
|
className="stg:mt-0.5 stg:size-3.5 stg:shrink-0 stg:text-muted-foreground"
|
|
100
111
|
/>
|
|
101
112
|
<span className="stg:min-w-0 stg:flex-1">
|
|
102
|
-
<span
|
|
113
|
+
<span
|
|
114
|
+
className={cn(
|
|
115
|
+
"stg:block stg:text-xs stg:font-medium",
|
|
116
|
+
locked ? "stg:text-muted-foreground" : "stg:text-foreground",
|
|
117
|
+
)}
|
|
118
|
+
>
|
|
103
119
|
{option.label}
|
|
104
120
|
</span>
|
|
105
121
|
<span className="stg:block stg:text-[0.65rem] stg:leading-snug stg:text-muted-foreground">
|
|
106
|
-
{option.description}
|
|
122
|
+
{locked ? option.lockedReason : option.description}
|
|
107
123
|
</span>
|
|
108
124
|
</span>
|
|
109
|
-
{
|
|
125
|
+
{locked ? (
|
|
126
|
+
<LockIcon className="stg:mt-0.5 stg:size-3.5 stg:shrink-0 stg:text-muted-foreground" />
|
|
127
|
+
) : (
|
|
128
|
+
isSelected && (
|
|
129
|
+
<CheckIcon className="stg:mt-0.5 stg:size-3.5 stg:shrink-0 stg:text-primary" />
|
|
130
|
+
)
|
|
131
|
+
)}
|
|
110
132
|
</button>
|
|
111
133
|
);
|
|
112
134
|
});
|
|
@@ -150,6 +150,12 @@ export function VisibilitySelector({
|
|
|
150
150
|
|
|
151
151
|
const handleSelect = useCallback(
|
|
152
152
|
(option: VisibilityLevelOption) => {
|
|
153
|
+
// Locked levels are not selectable; the row is disabled, this guard
|
|
154
|
+
// is defense in depth for programmatic activation.
|
|
155
|
+
if (option.lockedReason !== undefined) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
153
159
|
const value = option.value;
|
|
154
160
|
if (value === visibility) {
|
|
155
161
|
setPendingInline(null);
|
|
@@ -193,11 +199,17 @@ export function VisibilitySelector({
|
|
|
193
199
|
const moveFocus = useCallback(
|
|
194
200
|
(from: number, delta: number) => {
|
|
195
201
|
const count = effectiveOptions.length;
|
|
196
|
-
|
|
202
|
+
// Skip locked rows: their buttons are disabled and cannot take focus,
|
|
203
|
+
// so landing on one would strand the roving tabindex.
|
|
204
|
+
let next = from;
|
|
205
|
+
for (let step = 0; step < count; step++) {
|
|
206
|
+
next = (next + delta + count) % count;
|
|
207
|
+
if (effectiveOptions[next]?.lockedReason === undefined) break;
|
|
208
|
+
}
|
|
197
209
|
setHighlightIdx(next);
|
|
198
210
|
optionRefs.current[next]?.focus();
|
|
199
211
|
},
|
|
200
|
-
[effectiveOptions
|
|
212
|
+
[effectiveOptions],
|
|
201
213
|
);
|
|
202
214
|
|
|
203
215
|
const handleRowKeyDown = useCallback(
|
|
@@ -13,10 +13,14 @@ import {
|
|
|
13
13
|
VisibilityBadge,
|
|
14
14
|
} from "../VisibilitySelector";
|
|
15
15
|
import {
|
|
16
|
-
|
|
16
|
+
instanceVisibilityLevels,
|
|
17
17
|
blueprintVisibilityLevels,
|
|
18
18
|
} from "../visibilityLevels";
|
|
19
19
|
|
|
20
|
+
const INSTANCE_VISIBILITY_LEVELS = instanceVisibilityLevels({
|
|
21
|
+
canSetPublicVisibility: true,
|
|
22
|
+
});
|
|
23
|
+
|
|
20
24
|
// Base UI's Popover positioner observes its anchor; happy-dom lacks
|
|
21
25
|
// ResizeObserver, so provide a no-op shim.
|
|
22
26
|
beforeAll(() => {
|
|
@@ -35,6 +39,7 @@ afterEach(cleanup);
|
|
|
35
39
|
const BLUEPRINT_LEVELS = blueprintVisibilityLevels({
|
|
36
40
|
deploymentMode: "cloud",
|
|
37
41
|
hasIdentityProvider: true,
|
|
42
|
+
canSetPublicVisibility: true,
|
|
38
43
|
});
|
|
39
44
|
|
|
40
45
|
// Option accessible names are "<label> <description>"; anchor on the label so
|
|
@@ -118,6 +123,48 @@ describe("VisibilitySelector — create mode (inline list)", () => {
|
|
|
118
123
|
});
|
|
119
124
|
});
|
|
120
125
|
|
|
126
|
+
describe("VisibilitySelector — operator-gated Public (locked row)", () => {
|
|
127
|
+
// The caller may not publish: the level builders lock the Public row.
|
|
128
|
+
const GATED_LEVELS = instanceVisibilityLevels({
|
|
129
|
+
canSetPublicVisibility: false,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("renders the locked Public row non-interactive with the platform-team copy", () => {
|
|
133
|
+
const onChange = vi.fn();
|
|
134
|
+
render(
|
|
135
|
+
<VisibilitySelector
|
|
136
|
+
mode="create"
|
|
137
|
+
visibility={ApiResourceVisibility.visibility_private}
|
|
138
|
+
options={GATED_LEVELS}
|
|
139
|
+
onVisibilityChange={onChange}
|
|
140
|
+
/>,
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
const publicRow = screen.getByRole("radio", { name: /Public/i });
|
|
144
|
+
expect((publicRow as HTMLButtonElement).disabled).toBe(true);
|
|
145
|
+
expect(publicRow.getAttribute("aria-disabled")).toBe("true");
|
|
146
|
+
expect(publicRow.textContent).toContain("granted by the platform team");
|
|
147
|
+
|
|
148
|
+
fireEvent.click(publicRow);
|
|
149
|
+
expect(onChange).not.toHaveBeenCalled();
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it("keeps every other level selectable — only publishing is operator-granted", () => {
|
|
153
|
+
const onChange = vi.fn();
|
|
154
|
+
render(
|
|
155
|
+
<VisibilitySelector
|
|
156
|
+
mode="create"
|
|
157
|
+
visibility={ApiResourceVisibility.visibility_private}
|
|
158
|
+
options={GATED_LEVELS}
|
|
159
|
+
onVisibilityChange={onChange}
|
|
160
|
+
/>,
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
fireEvent.click(screen.getByRole("radio", { name: /^Organization/i }));
|
|
164
|
+
expect(onChange).toHaveBeenCalledWith(ApiResourceVisibility.visibility_org);
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
121
168
|
describe("VisibilitySelector — manage mode (popover + confirmation)", () => {
|
|
122
169
|
it("shows the current level on the trigger and lists levels on open", async () => {
|
|
123
170
|
render(
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
2
|
import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
blueprintVisibilityLevels,
|
|
5
|
+
environmentVisibilityLevels,
|
|
6
|
+
instanceVisibilityLevels,
|
|
7
|
+
PUBLIC_LOCKED_REASON,
|
|
8
|
+
type VisibilityLevelOption,
|
|
9
|
+
} from "../visibilityLevels";
|
|
4
10
|
|
|
5
11
|
describe("environmentVisibilityLevels", () => {
|
|
6
12
|
it("offers exactly Private and Organization in cloud mode", () => {
|
|
@@ -31,3 +37,63 @@ describe("environmentVisibilityLevels", () => {
|
|
|
31
37
|
expect(environmentVisibilityLevels("local")).toHaveLength(1);
|
|
32
38
|
});
|
|
33
39
|
});
|
|
40
|
+
|
|
41
|
+
describe("operator-gated PUBLIC level", () => {
|
|
42
|
+
const publicOf = (levels: readonly VisibilityLevelOption[]) =>
|
|
43
|
+
levels.find((l) => l.value === ApiResourceVisibility.visibility_public);
|
|
44
|
+
|
|
45
|
+
it("locks Public with the platform-team copy when the caller may not publish", () => {
|
|
46
|
+
const blueprint = publicOf(
|
|
47
|
+
blueprintVisibilityLevels({
|
|
48
|
+
deploymentMode: "cloud",
|
|
49
|
+
hasIdentityProvider: false,
|
|
50
|
+
canSetPublicVisibility: false,
|
|
51
|
+
}),
|
|
52
|
+
);
|
|
53
|
+
const instance = publicOf(
|
|
54
|
+
instanceVisibilityLevels({ canSetPublicVisibility: false }),
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
expect(blueprint?.lockedReason).toBe(PUBLIC_LOCKED_REASON);
|
|
58
|
+
expect(instance?.lockedReason).toBe(PUBLIC_LOCKED_REASON);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("offers Public unlocked for callers with the publish grant", () => {
|
|
62
|
+
const blueprint = publicOf(
|
|
63
|
+
blueprintVisibilityLevels({
|
|
64
|
+
deploymentMode: "cloud",
|
|
65
|
+
hasIdentityProvider: true,
|
|
66
|
+
canSetPublicVisibility: true,
|
|
67
|
+
}),
|
|
68
|
+
);
|
|
69
|
+
const instance = publicOf(
|
|
70
|
+
instanceVisibilityLevels({ canSetPublicVisibility: true }),
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
expect(blueprint?.lockedReason).toBeUndefined();
|
|
74
|
+
expect(instance?.lockedReason).toBeUndefined();
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("never locks any level below Public — org/platform sharing stays self-service", () => {
|
|
78
|
+
const levels = blueprintVisibilityLevels({
|
|
79
|
+
deploymentMode: "cloud",
|
|
80
|
+
hasIdentityProvider: true,
|
|
81
|
+
canSetPublicVisibility: false,
|
|
82
|
+
});
|
|
83
|
+
for (const level of levels) {
|
|
84
|
+
if (level.value === ApiResourceVisibility.visibility_public) continue;
|
|
85
|
+
expect(level.lockedReason, `${level.label} must stay self-service`).toBeUndefined();
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it("keeps the instance Public row's execution-oriented description when locked", () => {
|
|
90
|
+
// The lock replaces the rendered detail line, but the option data keeps
|
|
91
|
+
// its identity (label, tone, confirmation) so an unlock is a pure
|
|
92
|
+
// context change.
|
|
93
|
+
const instance = publicOf(
|
|
94
|
+
instanceVisibilityLevels({ canSetPublicVisibility: false }),
|
|
95
|
+
);
|
|
96
|
+
expect(instance?.lockedReason).toBe(PUBLIC_LOCKED_REASON);
|
|
97
|
+
expect(instance?.confirmDialog).toBeDefined();
|
|
98
|
+
});
|
|
99
|
+
});
|
package/src/library/index.ts
CHANGED
|
@@ -63,12 +63,14 @@ export type {
|
|
|
63
63
|
|
|
64
64
|
export {
|
|
65
65
|
blueprintVisibilityLevels,
|
|
66
|
-
|
|
66
|
+
instanceVisibilityLevels,
|
|
67
|
+
PUBLIC_LOCKED_REASON,
|
|
67
68
|
visibilityLabel,
|
|
68
69
|
visibilityOption,
|
|
69
70
|
} from "./visibilityLevels.js";
|
|
70
71
|
export type {
|
|
71
72
|
BlueprintVisibilityLevelsContext,
|
|
73
|
+
InstanceVisibilityLevelsContext,
|
|
72
74
|
VisibilityLevelOption,
|
|
73
75
|
} from "./visibilityLevels.js";
|
|
74
76
|
|
|
@@ -81,5 +83,8 @@ export type {
|
|
|
81
83
|
UseUpdateVisibilityReturn,
|
|
82
84
|
} from "./useUpdateVisibility.js";
|
|
83
85
|
|
|
86
|
+
export { useCanSetPublicVisibility } from "./useCanSetPublicVisibility.js";
|
|
87
|
+
export type { UseCanSetPublicVisibilityReturn } from "./useCanSetPublicVisibility.js";
|
|
88
|
+
|
|
84
89
|
export { InstanceVisibilitySelector } from "./InstanceVisibilitySelector.js";
|
|
85
90
|
export type { InstanceVisibilitySelectorProps } from "./InstanceVisibilitySelector.js";
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useDeploymentMode } from "../deployment-mode.js";
|
|
4
|
+
import { useCheckPermission } from "../iam-policy/useCheckPermission.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The `platform` singleton — platform-level permissions are always checked
|
|
8
|
+
* against this one resource (mirrors the server-side `resource_id = "stigmer"`
|
|
9
|
+
* RPC config).
|
|
10
|
+
*/
|
|
11
|
+
const PLATFORM_RESOURCE = { kind: "platform", id: "stigmer" } as const;
|
|
12
|
+
|
|
13
|
+
/** Return value of {@link useCanSetPublicVisibility}. */
|
|
14
|
+
export interface UseCanSetPublicVisibilityReturn {
|
|
15
|
+
/** Whether the current user may set resources to PUBLIC visibility. */
|
|
16
|
+
readonly allowed: boolean;
|
|
17
|
+
/** `true` while the permission check is in flight (cloud only). */
|
|
18
|
+
readonly isLoading: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Whether the current user may set a resource's visibility to PUBLIC — the
|
|
23
|
+
* only level that crosses every org boundary (the cross-org "explore"
|
|
24
|
+
* catalog).
|
|
25
|
+
*
|
|
26
|
+
* In the cloud edition, publishing is a curation decision: the backend
|
|
27
|
+
* gates both write doors (updateVisibility escalation and
|
|
28
|
+
* create-with-public) on `can_set_public_visibility` on `platform:stigmer`,
|
|
29
|
+
* an explicit platform-operator capability. This hook runs the same check
|
|
30
|
+
* so selectors can present the Public option as locked instead of letting
|
|
31
|
+
* the request fail.
|
|
32
|
+
*
|
|
33
|
+
* Fail-closed, deliberately the opposite of the `useCheckPermission`
|
|
34
|
+
* default: an escalation gate must not open while the check is loading or
|
|
35
|
+
* when it errors — a locked option that unlocks a moment later is a far
|
|
36
|
+
* better failure than an unlocked option the server then rejects.
|
|
37
|
+
*
|
|
38
|
+
* In `local` deployment mode (OSS Go backend) the answer is always `true`:
|
|
39
|
+
* the self-hosted operator owns the store, the same scoping cloud#320
|
|
40
|
+
* applied to reserved labels.
|
|
41
|
+
*/
|
|
42
|
+
export function useCanSetPublicVisibility(): UseCanSetPublicVisibilityReturn {
|
|
43
|
+
const deploymentMode = useDeploymentMode();
|
|
44
|
+
// Hooks run unconditionally; in local mode the null resource skips the
|
|
45
|
+
// RPC entirely and the fail mode's answer is discarded below.
|
|
46
|
+
const { allowed, isLoading } = useCheckPermission(
|
|
47
|
+
deploymentMode === "cloud" ? PLATFORM_RESOURCE : null,
|
|
48
|
+
"can_set_public_visibility",
|
|
49
|
+
{ fail: "closed" },
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
if (deploymentMode === "local") {
|
|
53
|
+
return { allowed: true, isLoading: false };
|
|
54
|
+
}
|
|
55
|
+
return { allowed, isLoading };
|
|
56
|
+
}
|
|
@@ -43,8 +43,28 @@ export interface VisibilityLevelOption {
|
|
|
43
43
|
};
|
|
44
44
|
/** Color treatment for the selected segment and the confirmation prompt. */
|
|
45
45
|
readonly tone: "private" | "org" | "platform" | "public";
|
|
46
|
+
/**
|
|
47
|
+
* When present, the level cannot be selected by the current caller and the
|
|
48
|
+
* row renders locked (disabled, lock affordance) with this copy explaining
|
|
49
|
+
* why and what to do instead. Computed by the level builders from caller
|
|
50
|
+
* context — the component stays free of per-level branching, exactly like
|
|
51
|
+
* the confirmation ladder.
|
|
52
|
+
*
|
|
53
|
+
* Today's only locked level is Public in the cloud edition for callers
|
|
54
|
+
* without `can_set_public_visibility` (publishing is operator-granted);
|
|
55
|
+
* the backend independently enforces the same gate.
|
|
56
|
+
*/
|
|
57
|
+
readonly lockedReason?: string;
|
|
46
58
|
}
|
|
47
59
|
|
|
60
|
+
/**
|
|
61
|
+
* The locked-row copy for a caller who may not set PUBLIC visibility. Names
|
|
62
|
+
* the path forward (ask the platform team) rather than a bare "disabled" —
|
|
63
|
+
* the option stays discoverable even though it is not self-service.
|
|
64
|
+
*/
|
|
65
|
+
export const PUBLIC_LOCKED_REASON =
|
|
66
|
+
"Public listing is granted by the platform team — contact us to publish this resource.";
|
|
67
|
+
|
|
48
68
|
const PRIVATE_OPTION: VisibilityLevelOption = {
|
|
49
69
|
value: ApiResourceVisibility.visibility_private,
|
|
50
70
|
label: "Private",
|
|
@@ -97,10 +117,27 @@ const PUBLIC_OPTION: VisibilityLevelOption = {
|
|
|
97
117
|
* operate an IdentityProvider — the backend rejects it otherwise
|
|
98
118
|
* (`ValidateVisibilityStep`), so the option only renders when the signal
|
|
99
119
|
* is present (use `useSsoProvider`, the permission-free lookup).
|
|
120
|
+
* - `canSetPublicVisibility`: entering PUBLIC is operator-gated in the
|
|
121
|
+
* cloud edition; when the caller lacks the grant the Public option
|
|
122
|
+
* renders locked instead of disappearing (use
|
|
123
|
+
* `useCanSetPublicVisibility`, which is always `true` in local mode).
|
|
100
124
|
*/
|
|
101
125
|
export interface BlueprintVisibilityLevelsContext {
|
|
102
126
|
readonly deploymentMode: "cloud" | "local";
|
|
103
127
|
readonly hasIdentityProvider: boolean;
|
|
128
|
+
readonly canSetPublicVisibility: boolean;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* The PUBLIC option, locked with {@link PUBLIC_LOCKED_REASON} when the
|
|
133
|
+
* caller may not publish. Locked rather than hidden: the level (and the
|
|
134
|
+
* path to it) stays discoverable, matching how the option keeps rendering
|
|
135
|
+
* as the current state on already-public resources.
|
|
136
|
+
*/
|
|
137
|
+
function publicOption(canSetPublicVisibility: boolean): VisibilityLevelOption {
|
|
138
|
+
return canSetPublicVisibility
|
|
139
|
+
? PUBLIC_OPTION
|
|
140
|
+
: { ...PUBLIC_OPTION, lockedReason: PUBLIC_LOCKED_REASON };
|
|
104
141
|
}
|
|
105
142
|
|
|
106
143
|
/**
|
|
@@ -114,12 +151,22 @@ export interface BlueprintVisibilityLevelsContext {
|
|
|
114
151
|
export function blueprintVisibilityLevels(
|
|
115
152
|
context: BlueprintVisibilityLevelsContext,
|
|
116
153
|
): readonly VisibilityLevelOption[] {
|
|
154
|
+
const publicLevel = publicOption(context.canSetPublicVisibility);
|
|
117
155
|
if (context.deploymentMode === "local") {
|
|
118
|
-
return [PRIVATE_OPTION,
|
|
156
|
+
return [PRIVATE_OPTION, publicLevel];
|
|
119
157
|
}
|
|
120
158
|
return context.hasIdentityProvider
|
|
121
|
-
? [PRIVATE_OPTION, ORG_OPTION, PLATFORM_OPTION,
|
|
122
|
-
: [PRIVATE_OPTION, ORG_OPTION,
|
|
159
|
+
? [PRIVATE_OPTION, ORG_OPTION, PLATFORM_OPTION, publicLevel]
|
|
160
|
+
: [PRIVATE_OPTION, ORG_OPTION, publicLevel];
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Inputs that gate the instance level set — only the publish gate; the set
|
|
165
|
+
* itself is fixed (instances have no platform level and no deployment-mode
|
|
166
|
+
* collapse).
|
|
167
|
+
*/
|
|
168
|
+
export interface InstanceVisibilityLevelsContext {
|
|
169
|
+
readonly canSetPublicVisibility: boolean;
|
|
123
170
|
}
|
|
124
171
|
|
|
125
172
|
/**
|
|
@@ -131,17 +178,21 @@ export function blueprintVisibilityLevels(
|
|
|
131
178
|
* boundary). Descriptions are execution-oriented because org visibility on
|
|
132
179
|
* an instance is about who can run it and see its executions.
|
|
133
180
|
*/
|
|
134
|
-
export
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
181
|
+
export function instanceVisibilityLevels(
|
|
182
|
+
context: InstanceVisibilityLevelsContext,
|
|
183
|
+
): readonly VisibilityLevelOption[] {
|
|
184
|
+
return [
|
|
185
|
+
PRIVATE_OPTION,
|
|
186
|
+
{
|
|
187
|
+
...ORG_OPTION,
|
|
188
|
+
description: "All org members can view executions",
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
...publicOption(context.canSetPublicVisibility),
|
|
192
|
+
description: "All authenticated users can view",
|
|
193
|
+
},
|
|
194
|
+
];
|
|
195
|
+
}
|
|
145
196
|
|
|
146
197
|
/**
|
|
147
198
|
* The levels an environment selector offers, in escalation order:
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { lazy, Suspense, useCallback, useEffect, useRef } from "react";
|
|
4
4
|
import { cn } from "@stigmer/theme";
|
|
5
5
|
import { DialogShell } from "../internal/DialogShell.js";
|
|
6
|
+
import { UNSTYLED_LIST } from "../internal/element-resets.js";
|
|
6
7
|
import { toast } from "../feedback/toast.js";
|
|
7
8
|
import { RedactedSecretsNotice } from "./RedactedSecretsNotice.js";
|
|
8
9
|
import {
|
|
@@ -189,7 +190,7 @@ export function ApplyManifestDialog({
|
|
|
189
190
|
|
|
190
191
|
{/* Per-document preview */}
|
|
191
192
|
{manifest.entries && manifest.entries.length > 0 && (
|
|
192
|
-
<ul className="stg:flex stg:max-h-48 stg:flex-col stg:gap-2 stg:overflow-y-auto" aria-label="Resources to apply">
|
|
193
|
+
<ul className={cn(UNSTYLED_LIST, "stg:flex stg:max-h-48 stg:flex-col stg:gap-2 stg:overflow-y-auto")} aria-label="Resources to apply">
|
|
193
194
|
{manifest.entries.map((entry, index) => (
|
|
194
195
|
<PreviewRow key={`${entry.document.handler.yamlKind}/${entry.document.org}/${entry.document.slug}/${index}`} entry={entry} />
|
|
195
196
|
))}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// Pins the connect hook's ride on the async connect lane (stigmer#425):
|
|
2
|
+
// startConnect + poll on a backend that serves it, and the blocking-RPC
|
|
3
|
+
// fallback on one that does not (the byoaEditionDegradation idiom — every
|
|
4
|
+
// OTHER mcp-server test in this suite exercises the fallback implicitly, this
|
|
5
|
+
// file pins BOTH lanes explicitly so neither can regress silently). The
|
|
6
|
+
// protocol's own edge cases (deadlines, rehydration codes) are pinned in
|
|
7
|
+
// @stigmer/sdk's mcpserver-connect.test.ts — this is the hook-level contract.
|
|
8
|
+
|
|
9
|
+
import { describe, it, expect, afterEach } from "vitest";
|
|
10
|
+
import { renderHook, act, cleanup } from "@testing-library/react";
|
|
11
|
+
import type { ReactNode } from "react";
|
|
12
|
+
import { create } from "@bufbuild/protobuf";
|
|
13
|
+
import { createRouterTransport } from "@connectrpc/connect";
|
|
14
|
+
import { Stigmer } from "@stigmer/sdk";
|
|
15
|
+
import { McpServerCommandController } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/command_pb";
|
|
16
|
+
import { McpServerQueryController } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/query_pb";
|
|
17
|
+
import { McpServerSchema } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/api_pb";
|
|
18
|
+
import { ConnectPhase } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/status_pb";
|
|
19
|
+
import { StigmerContext } from "../../context";
|
|
20
|
+
import { useMcpServerConnect } from "../useMcpServerConnect";
|
|
21
|
+
|
|
22
|
+
afterEach(cleanup);
|
|
23
|
+
|
|
24
|
+
const SERVER_ID = "mcps_01test";
|
|
25
|
+
const ORG = "acme";
|
|
26
|
+
|
|
27
|
+
function mcpServer(phase: ConnectPhase, extras?: { failureMessage?: string; toolName?: string }) {
|
|
28
|
+
return create(McpServerSchema, {
|
|
29
|
+
metadata: { id: SERVER_ID, name: "Test Server" },
|
|
30
|
+
status: {
|
|
31
|
+
...(extras?.toolName !== undefined
|
|
32
|
+
? { discoveredCapabilities: { tools: [{ name: extras.toolName }] } }
|
|
33
|
+
: {}),
|
|
34
|
+
connectStatus: {
|
|
35
|
+
phase,
|
|
36
|
+
workflowId: `stigmer/mcp-server/connect/${SERVER_ID}`,
|
|
37
|
+
failureCode: extras?.failureMessage !== undefined ? "FailedPrecondition" : "",
|
|
38
|
+
failureMessage: extras?.failureMessage ?? "",
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function renderConnectHook(register: Parameters<typeof createRouterTransport>[0]) {
|
|
45
|
+
const client = new Stigmer({
|
|
46
|
+
baseUrl: "/",
|
|
47
|
+
getAccessToken: () => "test-token",
|
|
48
|
+
customTransport: createRouterTransport(register),
|
|
49
|
+
});
|
|
50
|
+
const wrapper = ({ children }: { children: ReactNode }) => (
|
|
51
|
+
<StigmerContext.Provider value={client}>{children}</StigmerContext.Provider>
|
|
52
|
+
);
|
|
53
|
+
return renderHook(() => useMcpServerConnect(), { wrapper });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
describe("useMcpServerConnect — async lane", () => {
|
|
57
|
+
it("resolves through startConnect + polling when the backend serves the lane", async () => {
|
|
58
|
+
let blockingConnectCalled = false;
|
|
59
|
+
const { result } = renderConnectHook((router) => {
|
|
60
|
+
router.service(McpServerCommandController, {
|
|
61
|
+
startConnect: () => mcpServer(ConnectPhase.connecting),
|
|
62
|
+
connect: () => {
|
|
63
|
+
blockingConnectCalled = true;
|
|
64
|
+
return mcpServer(ConnectPhase.succeeded);
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
router.service(McpServerQueryController, {
|
|
68
|
+
get: () => mcpServer(ConnectPhase.succeeded, { toolName: "search_code" }),
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
await act(async () => {
|
|
73
|
+
const settled = await result.current.connect(SERVER_ID, ORG);
|
|
74
|
+
expect(settled.status?.discoveredCapabilities?.tools[0]?.name).toBe("search_code");
|
|
75
|
+
});
|
|
76
|
+
expect(blockingConnectCalled).toBe(false);
|
|
77
|
+
expect(result.current.error).toBeNull();
|
|
78
|
+
expect(result.current.isConnecting).toBe(false);
|
|
79
|
+
}, 15_000);
|
|
80
|
+
|
|
81
|
+
it("surfaces a failed operation with the persisted user-facing message", async () => {
|
|
82
|
+
const { result } = renderConnectHook((router) => {
|
|
83
|
+
router.service(McpServerCommandController, {
|
|
84
|
+
startConnect: () => mcpServer(ConnectPhase.connecting),
|
|
85
|
+
});
|
|
86
|
+
router.service(McpServerQueryController, {
|
|
87
|
+
get: () =>
|
|
88
|
+
mcpServer(ConnectPhase.failed, {
|
|
89
|
+
failureMessage: "connect failed for MCP server 'Test Server': missing credentials",
|
|
90
|
+
}),
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
await act(async () => {
|
|
95
|
+
await expect(result.current.connect(SERVER_ID, ORG)).rejects.toThrow("missing credentials");
|
|
96
|
+
});
|
|
97
|
+
expect(result.current.error?.message).toContain("missing credentials");
|
|
98
|
+
expect(result.current.isConnecting).toBe(false);
|
|
99
|
+
}, 15_000);
|
|
100
|
+
|
|
101
|
+
it("falls back to the blocking connect on a backend without the lane", async () => {
|
|
102
|
+
// startConnect deliberately unregistered: the router answers
|
|
103
|
+
// UNIMPLEMENTED, exactly what a pre-#425 backend (e.g. the hosted
|
|
104
|
+
// edition until its parity lands) returns.
|
|
105
|
+
const { result } = renderConnectHook((router) => {
|
|
106
|
+
router.service(McpServerCommandController, {
|
|
107
|
+
connect: () => mcpServer(ConnectPhase.succeeded, { toolName: "search_code" }),
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
await act(async () => {
|
|
112
|
+
const settled = await result.current.connect(SERVER_ID, ORG);
|
|
113
|
+
expect(settled.status?.discoveredCapabilities?.tools[0]?.name).toBe("search_code");
|
|
114
|
+
});
|
|
115
|
+
expect(result.current.error).toBeNull();
|
|
116
|
+
});
|
|
117
|
+
});
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useCallback, useId } from "react";
|
|
4
4
|
import { cn } from "@stigmer/theme";
|
|
5
|
+
import { UNSTYLED_FIELDSET } from "../../internal/element-resets.js";
|
|
5
6
|
import { generateSlug } from "../../internal/slug.js";
|
|
6
7
|
import type { McpServerWizardData, KeyValueEntry } from "./types.js";
|
|
7
8
|
|
|
@@ -179,7 +180,7 @@ export function IdentityTransportStep({
|
|
|
179
180
|
/>
|
|
180
181
|
</div>
|
|
181
182
|
|
|
182
|
-
<fieldset className="stg:space-y-1.5">
|
|
183
|
+
<fieldset className={cn(UNSTYLED_FIELDSET, "stg:space-y-1.5")}>
|
|
183
184
|
<legend className="stg:text-sm stg:font-medium stg:text-foreground">
|
|
184
185
|
Visibility
|
|
185
186
|
</legend>
|
|
@@ -204,7 +205,7 @@ export function IdentityTransportStep({
|
|
|
204
205
|
|
|
205
206
|
{/* data-scroll-target: guided tours/demos scroll the transport config
|
|
206
207
|
(the step's decision point) into view within the wizard's scroll area. */}
|
|
207
|
-
<fieldset className="stg:space-y-3" data-scroll-target="mcp-transport">
|
|
208
|
+
<fieldset className={cn(UNSTYLED_FIELDSET, "stg:space-y-3")} data-scroll-target="mcp-transport">
|
|
208
209
|
<legend className="stg:text-sm stg:font-medium stg:text-foreground">
|
|
209
210
|
Transport <span className="stg:text-destructive">*</span>
|
|
210
211
|
</legend>
|
|
@@ -4,7 +4,7 @@ import { useCallback, useState } from "react";
|
|
|
4
4
|
import { create } from "@bufbuild/protobuf";
|
|
5
5
|
import type { McpServer } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/api_pb";
|
|
6
6
|
import { ConnectInputSchema } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/io_pb";
|
|
7
|
-
import type
|
|
7
|
+
import { connectAndWait, type EnvVarInput } from "@stigmer/sdk";
|
|
8
8
|
import { useStigmer } from "../hooks.js";
|
|
9
9
|
import { resolveDeclaredSystemEnvVars } from "../environment/systemEnvVars.js";
|
|
10
10
|
import { toError } from "../internal/toError.js";
|
|
@@ -15,9 +15,12 @@ export interface UseMcpServerConnectReturn {
|
|
|
15
15
|
* Connect to an MCP server: discover its tools, resource templates,
|
|
16
16
|
* and classify tool approval policies via a lightweight LLM call.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* Uses the async connect lane (`startConnect` + polling via the SDK's
|
|
19
|
+
* `connectAndWait`, stigmer/stigmer#425): the promise still resolves
|
|
20
|
+
* when the operation settles — legitimately tens of seconds to minutes
|
|
21
|
+
* for heavy servers — but no RPC stays open that long, so the wait
|
|
22
|
+
* survives browser transport limits. Backends without the lane fall
|
|
23
|
+
* back to the blocking `connect` RPC transparently.
|
|
21
24
|
*
|
|
22
25
|
* Platform system env vars (`STIGMER_SERVER_ADDRESS`,
|
|
23
26
|
* `STIGMER_API_KEY`) are injected only when the MCP server
|
|
@@ -45,7 +48,7 @@ export interface UseMcpServerConnectReturn {
|
|
|
45
48
|
runtimeEnv?: Record<string, EnvVarInput>,
|
|
46
49
|
declaredEnvKeys?: readonly string[],
|
|
47
50
|
) => Promise<McpServer>;
|
|
48
|
-
/** `true` while the connect
|
|
51
|
+
/** `true` while the connect operation is in flight (start through settle). */
|
|
49
52
|
readonly isConnecting: boolean;
|
|
50
53
|
/** Error from the most recent failed connect, or `null`. */
|
|
51
54
|
readonly error: Error | null;
|
|
@@ -129,7 +132,7 @@ export function useMcpServerConnect(): UseMcpServerConnectReturn {
|
|
|
129
132
|
: {}),
|
|
130
133
|
});
|
|
131
134
|
|
|
132
|
-
return await stigmer.mcpServer
|
|
135
|
+
return await connectAndWait(stigmer.mcpServer, input);
|
|
133
136
|
} catch (err) {
|
|
134
137
|
const wrapped = toError(err);
|
|
135
138
|
setError(wrapped);
|