@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
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
4
4
|
import { create } from "@bufbuild/protobuf";
|
|
5
|
-
import { getUserMessage } from "@stigmer/sdk";
|
|
5
|
+
import { connectAndWait, getUserMessage } from "@stigmer/sdk";
|
|
6
6
|
import type { McpServer } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/api_pb";
|
|
7
7
|
import {
|
|
8
8
|
InitiateOAuthConnectInputSchema,
|
|
@@ -248,7 +248,12 @@ export function useMcpServerOAuthConnect(): UseMcpServerOAuthConnectReturn {
|
|
|
248
248
|
: {}),
|
|
249
249
|
});
|
|
250
250
|
|
|
251
|
-
|
|
251
|
+
// Async connect lane (stigmer/stigmer#425): startConnect + poll via
|
|
252
|
+
// the SDK's shared protocol, so the discovery wait can outlive the
|
|
253
|
+
// browser's ~300s no-bytes unary limit that used to fail this phase
|
|
254
|
+
// spuriously. Old backends without the lane fall back to the
|
|
255
|
+
// blocking RPC inside connectAndWait.
|
|
256
|
+
const server = await connectAndWait(stigmer.mcpServer, input);
|
|
252
257
|
|
|
253
258
|
advancePhase("done");
|
|
254
259
|
return server;
|
|
@@ -4,7 +4,10 @@ import { type FormEvent, useCallback, useId, useState } from "react";
|
|
|
4
4
|
import { cn } from "@stigmer/theme";
|
|
5
5
|
import { getUserMessage } from "@stigmer/sdk";
|
|
6
6
|
import type { OAuthApp } from "@stigmer/protos/ai/stigmer/iam/oauthapp/v1/api_pb";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
TokenEndpointAuthMethod,
|
|
9
|
+
VendorApprovalStatus,
|
|
10
|
+
} from "@stigmer/protos/ai/stigmer/iam/oauthapp/v1/spec_pb";
|
|
8
11
|
import { useCreateOAuthApp } from "./useCreateOAuthApp.js";
|
|
9
12
|
import { SpinnerIcon } from "../internal/SpinnerIcon.js";
|
|
10
13
|
|
|
@@ -30,8 +33,8 @@ export interface CreateOAuthAppFormProps {
|
|
|
30
33
|
* Collects the required OAuth configuration: **name**, **provider**,
|
|
31
34
|
* **client ID**, **client secret**, **authorization URL**, and
|
|
32
35
|
* **token URL**. An expandable "Advanced" section provides optional
|
|
33
|
-
* fields for scopes, userinfo URL, scope parameter name,
|
|
34
|
-
* approval settings.
|
|
36
|
+
* fields for scopes, userinfo URL, scope parameter name, token endpoint
|
|
37
|
+
* auth method, and vendor approval settings.
|
|
35
38
|
*
|
|
36
39
|
* This is a pure presentational component with no dialog wrapper
|
|
37
40
|
* (headless-first). The parent is responsible for rendering it inside
|
|
@@ -71,6 +74,9 @@ export function CreateOAuthAppForm({
|
|
|
71
74
|
const [scopes, setScopes] = useState("");
|
|
72
75
|
const [userinfoUrl, setUserinfoUrl] = useState("");
|
|
73
76
|
const [scopeParameterName, setScopeParameterName] = useState("");
|
|
77
|
+
const [tokenEndpointAuthMethod, setTokenEndpointAuthMethod] = useState<
|
|
78
|
+
"unspecified" | "client_secret_basic" | "client_secret_post"
|
|
79
|
+
>("unspecified");
|
|
74
80
|
const [vendorApprovalStatus, setVendorApprovalStatus] = useState<
|
|
75
81
|
"unspecified" | "pending" | "approved" | "rejected"
|
|
76
82
|
>("unspecified");
|
|
@@ -117,6 +123,10 @@ export function CreateOAuthAppForm({
|
|
|
117
123
|
...(scopeParameterName.trim() && {
|
|
118
124
|
scopeParameterName: scopeParameterName.trim(),
|
|
119
125
|
}),
|
|
126
|
+
...(tokenEndpointAuthMethod !== "unspecified" && {
|
|
127
|
+
tokenEndpointAuthMethod:
|
|
128
|
+
TOKEN_AUTH_METHOD_MAP[tokenEndpointAuthMethod],
|
|
129
|
+
}),
|
|
120
130
|
...(vendorApprovalStatus !== "unspecified" && {
|
|
121
131
|
vendorApprovalStatus: APPROVAL_STATUS_MAP[vendorApprovalStatus],
|
|
122
132
|
}),
|
|
@@ -141,6 +151,7 @@ export function CreateOAuthAppForm({
|
|
|
141
151
|
scopes,
|
|
142
152
|
userinfoUrl,
|
|
143
153
|
scopeParameterName,
|
|
154
|
+
tokenEndpointAuthMethod,
|
|
144
155
|
vendorApprovalStatus,
|
|
145
156
|
vendorApprovalDocsUrl,
|
|
146
157
|
create,
|
|
@@ -259,6 +270,45 @@ export function CreateOAuthAppForm({
|
|
|
259
270
|
disabled={isCreating}
|
|
260
271
|
/>
|
|
261
272
|
|
|
273
|
+
<div className="stg:space-y-1">
|
|
274
|
+
<label
|
|
275
|
+
htmlFor={`${baseId}-token-auth-method`}
|
|
276
|
+
className="stg:text-xs stg:font-medium stg:text-foreground"
|
|
277
|
+
>
|
|
278
|
+
Token endpoint auth method
|
|
279
|
+
</label>
|
|
280
|
+
<select
|
|
281
|
+
id={`${baseId}-token-auth-method`}
|
|
282
|
+
value={tokenEndpointAuthMethod}
|
|
283
|
+
onChange={(e) =>
|
|
284
|
+
setTokenEndpointAuthMethod(
|
|
285
|
+
e.target.value as typeof tokenEndpointAuthMethod,
|
|
286
|
+
)
|
|
287
|
+
}
|
|
288
|
+
disabled={isCreating}
|
|
289
|
+
className={cn(
|
|
290
|
+
"stg:w-full stg:rounded-md stg:border stg:border-input stg:bg-background stg:px-2.5 stg:py-1.5 stg:text-xs stg:text-foreground",
|
|
291
|
+
"stg:focus-visible:outline-none stg:focus-visible:ring-1 stg:focus-visible:ring-ring",
|
|
292
|
+
"stg:disabled:pointer-events-none stg:disabled:opacity-50",
|
|
293
|
+
)}
|
|
294
|
+
>
|
|
295
|
+
<option value="unspecified">
|
|
296
|
+
Unspecified (treated as HTTP Basic)
|
|
297
|
+
</option>
|
|
298
|
+
<option value="client_secret_basic">
|
|
299
|
+
client_secret_basic (HTTP Basic header)
|
|
300
|
+
</option>
|
|
301
|
+
<option value="client_secret_post">
|
|
302
|
+
client_secret_post (form body)
|
|
303
|
+
</option>
|
|
304
|
+
</select>
|
|
305
|
+
<p className="stg:text-[0.65rem] stg:text-muted-foreground">
|
|
306
|
+
How the client secret is sent to the vendor's token
|
|
307
|
+
endpoint. Most vendors accept HTTP Basic; some (e.g.
|
|
308
|
+
HubSpot) require client_secret_post.
|
|
309
|
+
</p>
|
|
310
|
+
</div>
|
|
311
|
+
|
|
262
312
|
<div className="stg:space-y-1">
|
|
263
313
|
<label
|
|
264
314
|
htmlFor={`${baseId}-approval-status`}
|
|
@@ -354,6 +404,11 @@ const APPROVAL_STATUS_MAP = {
|
|
|
354
404
|
rejected: VendorApprovalStatus.REJECTED,
|
|
355
405
|
} as const;
|
|
356
406
|
|
|
407
|
+
const TOKEN_AUTH_METHOD_MAP = {
|
|
408
|
+
client_secret_basic: TokenEndpointAuthMethod.CLIENT_SECRET_BASIC,
|
|
409
|
+
client_secret_post: TokenEndpointAuthMethod.CLIENT_SECRET_POST,
|
|
410
|
+
} as const;
|
|
411
|
+
|
|
357
412
|
// ---------------------------------------------------------------------------
|
|
358
413
|
// FormField (internal)
|
|
359
414
|
// ---------------------------------------------------------------------------
|
|
@@ -4,7 +4,10 @@ import { type FormEvent, useCallback, useId, useState } from "react";
|
|
|
4
4
|
import { cn } from "@stigmer/theme";
|
|
5
5
|
import { getUserMessage } from "@stigmer/sdk";
|
|
6
6
|
import type { OAuthApp } from "@stigmer/protos/ai/stigmer/iam/oauthapp/v1/api_pb";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
TokenEndpointAuthMethod,
|
|
9
|
+
VendorApprovalStatus,
|
|
10
|
+
} from "@stigmer/protos/ai/stigmer/iam/oauthapp/v1/spec_pb";
|
|
8
11
|
import { timestampDate, type Timestamp } from "@bufbuild/protobuf/wkt";
|
|
9
12
|
import { useUpdateOAuthApp } from "./useUpdateOAuthApp.js";
|
|
10
13
|
import { useDeleteOAuthApp } from "./useDeleteOAuthApp.js";
|
|
@@ -87,6 +90,9 @@ export function OAuthAppDetailPanel({
|
|
|
87
90
|
const [scopeParameterName, setScopeParameterName] = useState(
|
|
88
91
|
spec?.scopeParameterName ?? "",
|
|
89
92
|
);
|
|
93
|
+
const [tokenEndpointAuthMethod, setTokenEndpointAuthMethod] = useState(
|
|
94
|
+
tokenAuthMethodToKey(spec?.tokenEndpointAuthMethod),
|
|
95
|
+
);
|
|
90
96
|
const [vendorApprovalStatus, setVendorApprovalStatus] = useState(
|
|
91
97
|
approvalStatusToKey(spec?.vendorApprovalStatus),
|
|
92
98
|
);
|
|
@@ -103,6 +109,7 @@ export function OAuthAppDetailPanel({
|
|
|
103
109
|
setScopes(spec?.scopes.join(", ") ?? "");
|
|
104
110
|
setUserinfoUrl(spec?.userinfoUrl ?? "");
|
|
105
111
|
setScopeParameterName(spec?.scopeParameterName ?? "");
|
|
112
|
+
setTokenEndpointAuthMethod(tokenAuthMethodToKey(spec?.tokenEndpointAuthMethod));
|
|
106
113
|
setVendorApprovalStatus(approvalStatusToKey(spec?.vendorApprovalStatus));
|
|
107
114
|
setVendorApprovalDocsUrl(spec?.vendorApprovalDocsUrl ?? "");
|
|
108
115
|
clearUpdateError();
|
|
@@ -139,6 +146,10 @@ export function OAuthAppDetailPanel({
|
|
|
139
146
|
...(scopeParameterName.trim() && {
|
|
140
147
|
scopeParameterName: scopeParameterName.trim(),
|
|
141
148
|
}),
|
|
149
|
+
...(tokenEndpointAuthMethod !== "unspecified" && {
|
|
150
|
+
tokenEndpointAuthMethod:
|
|
151
|
+
TOKEN_AUTH_METHOD_MAP[tokenEndpointAuthMethod],
|
|
152
|
+
}),
|
|
142
153
|
...(vendorApprovalStatus !== "unspecified" && {
|
|
143
154
|
vendorApprovalStatus: APPROVAL_STATUS_MAP[vendorApprovalStatus],
|
|
144
155
|
}),
|
|
@@ -154,8 +165,9 @@ export function OAuthAppDetailPanel({
|
|
|
154
165
|
},
|
|
155
166
|
[
|
|
156
167
|
meta, provider, clientId, clientSecret, authorizationUrl, tokenUrl,
|
|
157
|
-
scopes, userinfoUrl, scopeParameterName,
|
|
158
|
-
vendorApprovalDocsUrl, update, clearUpdateError,
|
|
168
|
+
scopes, userinfoUrl, scopeParameterName, tokenEndpointAuthMethod,
|
|
169
|
+
vendorApprovalStatus, vendorApprovalDocsUrl, update, clearUpdateError,
|
|
170
|
+
onUpdated,
|
|
159
171
|
],
|
|
160
172
|
);
|
|
161
173
|
|
|
@@ -372,6 +384,40 @@ export function OAuthAppDetailPanel({
|
|
|
372
384
|
disabled={isUpdating}
|
|
373
385
|
/>
|
|
374
386
|
|
|
387
|
+
<div className="stg:space-y-1">
|
|
388
|
+
<label
|
|
389
|
+
htmlFor={`${baseId}-token-auth-method`}
|
|
390
|
+
className="stg:text-xs stg:font-medium stg:text-foreground"
|
|
391
|
+
>
|
|
392
|
+
Token endpoint auth method
|
|
393
|
+
</label>
|
|
394
|
+
<select
|
|
395
|
+
id={`${baseId}-token-auth-method`}
|
|
396
|
+
value={tokenEndpointAuthMethod}
|
|
397
|
+
onChange={(e) =>
|
|
398
|
+
setTokenEndpointAuthMethod(
|
|
399
|
+
e.target.value as typeof tokenEndpointAuthMethod,
|
|
400
|
+
)
|
|
401
|
+
}
|
|
402
|
+
disabled={isUpdating}
|
|
403
|
+
className={cn(
|
|
404
|
+
"stg:w-full stg:rounded-md stg:border stg:border-input stg:bg-background stg:px-2.5 stg:py-1.5 stg:text-xs stg:text-foreground",
|
|
405
|
+
"stg:focus-visible:outline-none stg:focus-visible:ring-1 stg:focus-visible:ring-ring",
|
|
406
|
+
"stg:disabled:pointer-events-none stg:disabled:opacity-50",
|
|
407
|
+
)}
|
|
408
|
+
>
|
|
409
|
+
<option value="unspecified">
|
|
410
|
+
Unspecified (treated as HTTP Basic)
|
|
411
|
+
</option>
|
|
412
|
+
<option value="client_secret_basic">
|
|
413
|
+
client_secret_basic (HTTP Basic header)
|
|
414
|
+
</option>
|
|
415
|
+
<option value="client_secret_post">
|
|
416
|
+
client_secret_post (form body)
|
|
417
|
+
</option>
|
|
418
|
+
</select>
|
|
419
|
+
</div>
|
|
420
|
+
|
|
375
421
|
<div className="stg:space-y-1">
|
|
376
422
|
<label
|
|
377
423
|
htmlFor={`${baseId}-approval-status`}
|
|
@@ -481,6 +527,29 @@ function approvalStatusToKey(
|
|
|
481
527
|
}
|
|
482
528
|
}
|
|
483
529
|
|
|
530
|
+
const TOKEN_AUTH_METHOD_MAP = {
|
|
531
|
+
client_secret_basic: TokenEndpointAuthMethod.CLIENT_SECRET_BASIC,
|
|
532
|
+
client_secret_post: TokenEndpointAuthMethod.CLIENT_SECRET_POST,
|
|
533
|
+
} as const;
|
|
534
|
+
|
|
535
|
+
const TOKEN_AUTH_METHOD_LABELS: Record<number, string> = {
|
|
536
|
+
[TokenEndpointAuthMethod.CLIENT_SECRET_BASIC]: "client_secret_basic",
|
|
537
|
+
[TokenEndpointAuthMethod.CLIENT_SECRET_POST]: "client_secret_post",
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
function tokenAuthMethodToKey(
|
|
541
|
+
method?: TokenEndpointAuthMethod,
|
|
542
|
+
): "unspecified" | "client_secret_basic" | "client_secret_post" {
|
|
543
|
+
switch (method) {
|
|
544
|
+
case TokenEndpointAuthMethod.CLIENT_SECRET_BASIC:
|
|
545
|
+
return "client_secret_basic";
|
|
546
|
+
case TokenEndpointAuthMethod.CLIENT_SECRET_POST:
|
|
547
|
+
return "client_secret_post";
|
|
548
|
+
default:
|
|
549
|
+
return "unspecified";
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
484
553
|
// ---------------------------------------------------------------------------
|
|
485
554
|
// View mode
|
|
486
555
|
// ---------------------------------------------------------------------------
|
|
@@ -514,6 +583,18 @@ function ViewMode({
|
|
|
514
583
|
mono
|
|
515
584
|
/>
|
|
516
585
|
)}
|
|
586
|
+
{spec?.tokenEndpointAuthMethod !== undefined &&
|
|
587
|
+
spec.tokenEndpointAuthMethod !==
|
|
588
|
+
TokenEndpointAuthMethod.UNSPECIFIED && (
|
|
589
|
+
<Field
|
|
590
|
+
label="Token endpoint auth method"
|
|
591
|
+
value={
|
|
592
|
+
TOKEN_AUTH_METHOD_LABELS[spec.tokenEndpointAuthMethod] ??
|
|
593
|
+
"Unknown"
|
|
594
|
+
}
|
|
595
|
+
mono
|
|
596
|
+
/>
|
|
597
|
+
)}
|
|
517
598
|
{spec?.vendorApprovalStatus !== undefined &&
|
|
518
599
|
spec.vendorApprovalStatus !== VendorApprovalStatus.UNSPECIFIED && (
|
|
519
600
|
<Field
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { type FormEvent, useCallback, useEffect, useId, useMemo, useState } from "react";
|
|
4
|
+
import { cn } from "@stigmer/theme";
|
|
5
|
+
import { getUserMessage, toOrganizationUpdateInput } from "@stigmer/sdk";
|
|
6
|
+
import type { Organization } from "@stigmer/protos/ai/stigmer/tenancy/organization/v1/api_pb";
|
|
7
|
+
import { useOrganization } from "./useOrganization.js";
|
|
8
|
+
import { useUpdateOrganization } from "./useUpdateOrganization.js";
|
|
9
|
+
import { useCheckPermission } from "../iam-policy/useCheckPermission.js";
|
|
10
|
+
import { StandingContextField } from "../internal/StandingContextField.js";
|
|
11
|
+
import { SpinnerIcon } from "../internal/SpinnerIcon.js";
|
|
12
|
+
|
|
13
|
+
/** Props for {@link OrgPreferencesPanel}. */
|
|
14
|
+
export interface OrgPreferencesPanelProps {
|
|
15
|
+
/** The ID of the organization whose preferences to display and edit. */
|
|
16
|
+
readonly orgId: string;
|
|
17
|
+
/** Fired with the updated resource after a successful save. */
|
|
18
|
+
readonly onUpdated?: (org: Organization) => void;
|
|
19
|
+
/** Additional CSS class names for the root container. */
|
|
20
|
+
readonly className?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Self-contained editor for an {@link Organization}'s declared
|
|
25
|
+
* preferences (`spec.preferences.standing_context`).
|
|
26
|
+
*
|
|
27
|
+
* The declared text is snapshotted into every eligible agent execution
|
|
28
|
+
* run by the organization's members (first-party human operators only)
|
|
29
|
+
* and delivered to the agent as background context. Editing requires
|
|
30
|
+
* `can_edit` on the organization; viewers without it get a read-only
|
|
31
|
+
* rendering. On save, calls `organization.update()` with the complete
|
|
32
|
+
* mapped input (full-spec-replace safety) and fires `onUpdated`.
|
|
33
|
+
*
|
|
34
|
+
* All visual properties flow through `--stgm-*` design tokens. Zero
|
|
35
|
+
* dependencies on Console routing, auth context, or layout — platform
|
|
36
|
+
* builders can embed it directly:
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```tsx
|
|
40
|
+
* <OrgPreferencesPanel orgId="org-id-123" />
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export function OrgPreferencesPanel({
|
|
44
|
+
orgId,
|
|
45
|
+
onUpdated,
|
|
46
|
+
className,
|
|
47
|
+
}: OrgPreferencesPanelProps) {
|
|
48
|
+
const baseId = useId();
|
|
49
|
+
const {
|
|
50
|
+
organization,
|
|
51
|
+
isLoading: isFetching,
|
|
52
|
+
error: fetchError,
|
|
53
|
+
refetch,
|
|
54
|
+
} = useOrganization(orgId || null);
|
|
55
|
+
|
|
56
|
+
const {
|
|
57
|
+
update,
|
|
58
|
+
isUpdating,
|
|
59
|
+
error: updateError,
|
|
60
|
+
clearError,
|
|
61
|
+
} = useUpdateOrganization();
|
|
62
|
+
|
|
63
|
+
// Fail-open: OSS local mode has no IAM service, so editing stays
|
|
64
|
+
// available there; cloud gets a genuine server verdict.
|
|
65
|
+
const { allowed: canEdit } = useCheckPermission(
|
|
66
|
+
orgId ? { kind: "organization", id: orgId } : null,
|
|
67
|
+
"can_edit",
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
const [standingContext, setStandingContext] = useState("");
|
|
71
|
+
|
|
72
|
+
const serverStandingContext =
|
|
73
|
+
organization?.spec?.preferences?.standingContext ?? "";
|
|
74
|
+
|
|
75
|
+
// Sync the form field when server data changes.
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
if (!organization) return;
|
|
78
|
+
setStandingContext(
|
|
79
|
+
organization.spec?.preferences?.standingContext ?? "",
|
|
80
|
+
);
|
|
81
|
+
}, [organization]);
|
|
82
|
+
|
|
83
|
+
const hasChanges = useMemo(
|
|
84
|
+
() => standingContext.trim() !== serverStandingContext,
|
|
85
|
+
[standingContext, serverStandingContext],
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
const canSubmit = canEdit && hasChanges && !isUpdating;
|
|
89
|
+
|
|
90
|
+
const handleDiscard = useCallback(() => {
|
|
91
|
+
setStandingContext(serverStandingContext);
|
|
92
|
+
clearError();
|
|
93
|
+
}, [serverStandingContext, clearError]);
|
|
94
|
+
|
|
95
|
+
const handleSubmit = useCallback(
|
|
96
|
+
async (e: FormEvent) => {
|
|
97
|
+
e.preventDefault();
|
|
98
|
+
if (!canSubmit || !organization) return;
|
|
99
|
+
|
|
100
|
+
clearError();
|
|
101
|
+
try {
|
|
102
|
+
// update() is a full-spec replace: spread the complete mapped input
|
|
103
|
+
// so unedited spec fields survive, and override only preferences.
|
|
104
|
+
const updated = await update({
|
|
105
|
+
...toOrganizationUpdateInput(organization),
|
|
106
|
+
preferences: { standingContext: standingContext.trim() || undefined },
|
|
107
|
+
});
|
|
108
|
+
refetch();
|
|
109
|
+
onUpdated?.(updated);
|
|
110
|
+
} catch {
|
|
111
|
+
// error state is managed by useUpdateOrganization
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
[canSubmit, organization, standingContext, update, clearError, refetch, onUpdated],
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
// -----------------------------------------------------------------------
|
|
118
|
+
// Loading state
|
|
119
|
+
// -----------------------------------------------------------------------
|
|
120
|
+
|
|
121
|
+
if (isFetching && !organization) {
|
|
122
|
+
return (
|
|
123
|
+
<div
|
|
124
|
+
className={cn("stg:space-y-4", className)}
|
|
125
|
+
aria-busy="true"
|
|
126
|
+
aria-label="Loading organization preferences"
|
|
127
|
+
>
|
|
128
|
+
<div className="stg:bg-muted-subtle stg:h-28 stg:animate-pulse stg:rounded" />
|
|
129
|
+
<div className="stg:bg-muted-subtle stg:h-8 stg:w-32 stg:animate-pulse stg:rounded" />
|
|
130
|
+
</div>
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// -----------------------------------------------------------------------
|
|
135
|
+
// Fetch error
|
|
136
|
+
// -----------------------------------------------------------------------
|
|
137
|
+
|
|
138
|
+
if (fetchError) {
|
|
139
|
+
return (
|
|
140
|
+
<div className={cn("stg:space-y-3", className)} role="alert">
|
|
141
|
+
<p className="stg:text-destructive stg:text-sm">
|
|
142
|
+
{getUserMessage(fetchError)}
|
|
143
|
+
</p>
|
|
144
|
+
<button
|
|
145
|
+
type="button"
|
|
146
|
+
onClick={refetch}
|
|
147
|
+
className={cn(
|
|
148
|
+
"stg:rounded-md stg:px-3 stg:py-1.5 stg:text-xs stg:font-medium",
|
|
149
|
+
"stg:bg-primary stg:text-primary-foreground stg:hover:bg-primary-hover",
|
|
150
|
+
)}
|
|
151
|
+
>
|
|
152
|
+
Retry
|
|
153
|
+
</button>
|
|
154
|
+
</div>
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (!organization) return null;
|
|
159
|
+
|
|
160
|
+
// -----------------------------------------------------------------------
|
|
161
|
+
// Render
|
|
162
|
+
// -----------------------------------------------------------------------
|
|
163
|
+
|
|
164
|
+
return (
|
|
165
|
+
<form onSubmit={handleSubmit} className={cn("stg:space-y-4", className)}>
|
|
166
|
+
<StandingContextField
|
|
167
|
+
id={`${baseId}-standing-context`}
|
|
168
|
+
value={standingContext}
|
|
169
|
+
onChange={setStandingContext}
|
|
170
|
+
disabled={isUpdating}
|
|
171
|
+
readOnly={!canEdit}
|
|
172
|
+
placeholder={
|
|
173
|
+
"e.g. We deploy to us-east-1. Our stack is Go and TypeScript. Prefer concise answers."
|
|
174
|
+
}
|
|
175
|
+
helperText="Shared with agents as background context — not instructions. Applies to executions started by signed-in members of this organization and is visible on their execution records."
|
|
176
|
+
/>
|
|
177
|
+
|
|
178
|
+
{!canEdit && (
|
|
179
|
+
<p className="stg:text-[0.65rem] stg:text-muted-foreground">
|
|
180
|
+
Only organization admins can edit these preferences.
|
|
181
|
+
</p>
|
|
182
|
+
)}
|
|
183
|
+
|
|
184
|
+
{updateError && (
|
|
185
|
+
<p className="stg:text-destructive stg:text-[0.65rem]" role="alert">
|
|
186
|
+
{getUserMessage(updateError)}
|
|
187
|
+
</p>
|
|
188
|
+
)}
|
|
189
|
+
|
|
190
|
+
{canEdit && (
|
|
191
|
+
<div className="stg:flex stg:items-center stg:gap-2">
|
|
192
|
+
<button
|
|
193
|
+
type="submit"
|
|
194
|
+
disabled={!canSubmit}
|
|
195
|
+
className={cn(
|
|
196
|
+
"stg:inline-flex stg:items-center stg:gap-1.5 stg:rounded-md stg:px-3 stg:py-1.5 stg:text-xs stg:font-medium",
|
|
197
|
+
"stg:bg-primary stg:text-primary-foreground stg:hover:bg-primary-hover",
|
|
198
|
+
"stg:disabled:pointer-events-none stg:disabled:opacity-40",
|
|
199
|
+
)}
|
|
200
|
+
>
|
|
201
|
+
{isUpdating && <SpinnerIcon size={12} />}
|
|
202
|
+
Save changes
|
|
203
|
+
</button>
|
|
204
|
+
|
|
205
|
+
{hasChanges && !isUpdating && (
|
|
206
|
+
<button
|
|
207
|
+
type="button"
|
|
208
|
+
onClick={handleDiscard}
|
|
209
|
+
className={cn(
|
|
210
|
+
"stg:rounded-md stg:px-3 stg:py-1.5 stg:text-xs",
|
|
211
|
+
"stg:text-muted-foreground stg:hover:text-foreground stg:hover:bg-accent-hover",
|
|
212
|
+
)}
|
|
213
|
+
>
|
|
214
|
+
Discard
|
|
215
|
+
</button>
|
|
216
|
+
)}
|
|
217
|
+
</div>
|
|
218
|
+
)}
|
|
219
|
+
</form>
|
|
220
|
+
);
|
|
221
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { type FormEvent, useCallback, useEffect, useId, useMemo, useState } from "react";
|
|
4
4
|
import { cn } from "@stigmer/theme";
|
|
5
|
-
import { getUserMessage } from "@stigmer/sdk";
|
|
5
|
+
import { getUserMessage, toOrganizationUpdateInput } from "@stigmer/sdk";
|
|
6
6
|
import type { Organization } from "@stigmer/protos/ai/stigmer/tenancy/organization/v1/api_pb";
|
|
7
7
|
import { useOrganization } from "./useOrganization.js";
|
|
8
8
|
import { useUpdateOrganization } from "./useUpdateOrganization.js";
|
|
@@ -116,10 +116,12 @@ export function OrgProfilePanel({
|
|
|
116
116
|
|
|
117
117
|
clearError();
|
|
118
118
|
try {
|
|
119
|
+
// update() is a full-spec replace: spread the complete mapped input
|
|
120
|
+
// so unedited spec fields (e.g. preferences) survive the save, and
|
|
121
|
+
// override only the fields this form edits.
|
|
119
122
|
const updated = await update({
|
|
123
|
+
...toOrganizationUpdateInput(organization),
|
|
120
124
|
name: name.trim(),
|
|
121
|
-
slug: serverSlug,
|
|
122
|
-
org: serverSlug,
|
|
123
125
|
description: description.trim() || undefined,
|
|
124
126
|
logoUrl: logoUrl.trim() || undefined,
|
|
125
127
|
});
|
|
@@ -135,7 +137,6 @@ export function OrgProfilePanel({
|
|
|
135
137
|
name,
|
|
136
138
|
description,
|
|
137
139
|
logoUrl,
|
|
138
|
-
serverSlug,
|
|
139
140
|
update,
|
|
140
141
|
clearError,
|
|
141
142
|
refetch,
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { describe, it, expect, vi, afterEach } from "vitest";
|
|
2
|
+
import { cleanup, fireEvent, render, screen, waitFor } from "@testing-library/react";
|
|
3
|
+
import { create } from "@bufbuild/protobuf";
|
|
4
|
+
import {
|
|
5
|
+
OrganizationSchema,
|
|
6
|
+
type Organization,
|
|
7
|
+
} from "@stigmer/protos/ai/stigmer/tenancy/organization/v1/api_pb";
|
|
8
|
+
import type { OrganizationInput } from "@stigmer/sdk";
|
|
9
|
+
import { StigmerContext } from "../../context";
|
|
10
|
+
import { DeploymentModeContext } from "../../deployment-mode";
|
|
11
|
+
import { OrgPreferencesPanel } from "../OrgPreferencesPanel";
|
|
12
|
+
|
|
13
|
+
const ORG: Organization = create(OrganizationSchema, {
|
|
14
|
+
metadata: { id: "acme", name: "Acme Corp", slug: "acme", org: "acme" },
|
|
15
|
+
spec: {
|
|
16
|
+
description: "We make everything.",
|
|
17
|
+
logoUrl: "https://acme.example/logo.png",
|
|
18
|
+
preferences: { standingContext: "We deploy to us-east-1." },
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
function createMockStigmer(overrides?: {
|
|
23
|
+
update?: ReturnType<typeof vi.fn>;
|
|
24
|
+
canEdit?: boolean;
|
|
25
|
+
}) {
|
|
26
|
+
return {
|
|
27
|
+
organization: {
|
|
28
|
+
get: vi.fn(async () => ORG),
|
|
29
|
+
update: overrides?.update ?? vi.fn(async () => ORG),
|
|
30
|
+
},
|
|
31
|
+
iamPolicy: {
|
|
32
|
+
checkMyPermission: vi.fn(async () => ({
|
|
33
|
+
isAuthorized: overrides?.canEdit ?? true,
|
|
34
|
+
})),
|
|
35
|
+
},
|
|
36
|
+
} as never;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function renderPanel(client: unknown) {
|
|
40
|
+
return render(
|
|
41
|
+
<StigmerContext.Provider value={client as never}>
|
|
42
|
+
<DeploymentModeContext.Provider value="local">
|
|
43
|
+
<OrgPreferencesPanel orgId="acme" />
|
|
44
|
+
</DeploymentModeContext.Provider>
|
|
45
|
+
</StigmerContext.Provider>,
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
afterEach(cleanup);
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Waits until the form has synced from server data (the panel copies the
|
|
53
|
+
* fetched value into local state in a passive effect, one flush after the
|
|
54
|
+
* field first renders) — interacting earlier races the sync.
|
|
55
|
+
*/
|
|
56
|
+
async function findSyncedField(value: string) {
|
|
57
|
+
const field = await screen.findByLabelText("Standing context");
|
|
58
|
+
await waitFor(() => expect(field).toHaveProperty("value", value));
|
|
59
|
+
return field;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
describe("OrgPreferencesPanel", () => {
|
|
63
|
+
it("loads and displays the declared standing context", async () => {
|
|
64
|
+
renderPanel(createMockStigmer());
|
|
65
|
+
|
|
66
|
+
await findSyncedField("We deploy to us-east-1.");
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("saves the full mapped input — unedited profile fields survive (wipe-bug guard)", async () => {
|
|
70
|
+
const update = vi.fn(async (_input: OrganizationInput) => ORG);
|
|
71
|
+
renderPanel(createMockStigmer({ update }));
|
|
72
|
+
|
|
73
|
+
const field = await findSyncedField("We deploy to us-east-1.");
|
|
74
|
+
fireEvent.change(field, { target: { value: "Prefer terse answers." } });
|
|
75
|
+
fireEvent.click(screen.getByRole("button", { name: "Save changes" }));
|
|
76
|
+
|
|
77
|
+
await waitFor(() => expect(update).toHaveBeenCalledTimes(1));
|
|
78
|
+
const input = update.mock.calls[0]![0];
|
|
79
|
+
|
|
80
|
+
expect(input.preferences).toEqual({
|
|
81
|
+
standingContext: "Prefer terse answers.",
|
|
82
|
+
});
|
|
83
|
+
// Fields this form never renders must round-trip untouched.
|
|
84
|
+
expect(input.name).toBe("Acme Corp");
|
|
85
|
+
expect(input.description).toBe("We make everything.");
|
|
86
|
+
expect(input.logoUrl).toBe("https://acme.example/logo.png");
|
|
87
|
+
expect(input.org).toBe("acme");
|
|
88
|
+
expect(input.slug).toBe("acme");
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("clears the standing context when the text is emptied", async () => {
|
|
92
|
+
const update = vi.fn(async (_input: OrganizationInput) => ORG);
|
|
93
|
+
renderPanel(createMockStigmer({ update }));
|
|
94
|
+
|
|
95
|
+
const field = await findSyncedField("We deploy to us-east-1.");
|
|
96
|
+
fireEvent.change(field, { target: { value: "" } });
|
|
97
|
+
fireEvent.click(screen.getByRole("button", { name: "Save changes" }));
|
|
98
|
+
|
|
99
|
+
await waitFor(() => expect(update).toHaveBeenCalledTimes(1));
|
|
100
|
+
expect(update.mock.calls[0]![0].preferences).toEqual({
|
|
101
|
+
standingContext: undefined,
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it("discard resets the field to the server value", async () => {
|
|
106
|
+
renderPanel(createMockStigmer());
|
|
107
|
+
|
|
108
|
+
const field = await findSyncedField("We deploy to us-east-1.");
|
|
109
|
+
fireEvent.change(field, { target: { value: "Edited but regretted" } });
|
|
110
|
+
fireEvent.click(screen.getByRole("button", { name: "Discard" }));
|
|
111
|
+
|
|
112
|
+
expect(field).toHaveProperty("value", "We deploy to us-east-1.");
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it("renders read-only with an explanation when the caller lacks can_edit", async () => {
|
|
116
|
+
renderPanel(createMockStigmer({ canEdit: false }));
|
|
117
|
+
|
|
118
|
+
const field = await screen.findByLabelText("Standing context");
|
|
119
|
+
await waitFor(() =>
|
|
120
|
+
expect(field).toHaveProperty("readOnly", true),
|
|
121
|
+
);
|
|
122
|
+
expect(
|
|
123
|
+
screen.getByText("Only organization admins can edit these preferences."),
|
|
124
|
+
).toBeTruthy();
|
|
125
|
+
expect(screen.queryByRole("button", { name: "Save changes" })).toBeNull();
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it("shows the fetch error with a retry action when loading fails", async () => {
|
|
129
|
+
const client = {
|
|
130
|
+
organization: {
|
|
131
|
+
get: vi.fn(async () => {
|
|
132
|
+
throw new Error("boom");
|
|
133
|
+
}),
|
|
134
|
+
update: vi.fn(),
|
|
135
|
+
},
|
|
136
|
+
iamPolicy: {
|
|
137
|
+
checkMyPermission: vi.fn(async () => ({ isAuthorized: true })),
|
|
138
|
+
},
|
|
139
|
+
} as never;
|
|
140
|
+
renderPanel(client);
|
|
141
|
+
|
|
142
|
+
expect(await screen.findByRole("alert")).toBeTruthy();
|
|
143
|
+
expect(screen.getByRole("button", { name: "Retry" })).toBeTruthy();
|
|
144
|
+
});
|
|
145
|
+
});
|