@stigmer/react 3.40.0 → 3.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/access/ManageAccessDialog.d.ts +1 -1
- package/access/ManageAccessDialog.js +1 -1
- package/access/types.d.ts +1 -1
- package/billing/ChangePlanDialog.d.ts.map +1 -1
- package/billing/ChangePlanDialog.js +13 -1
- package/billing/ChangePlanDialog.js.map +1 -1
- package/billing/ProviderKeysSection.d.ts +33 -0
- package/billing/ProviderKeysSection.d.ts.map +1 -0
- package/billing/ProviderKeysSection.js +143 -0
- package/billing/ProviderKeysSection.js.map +1 -0
- package/billing/UpgradeNotice.d.ts.map +1 -1
- package/billing/UpgradeNotice.js +1 -0
- package/billing/UpgradeNotice.js.map +1 -1
- package/billing/index.d.ts +4 -0
- package/billing/index.d.ts.map +1 -1
- package/billing/index.js +2 -0
- package/billing/index.js.map +1 -1
- package/billing/plan-features.d.ts +3 -2
- package/billing/plan-features.d.ts.map +1 -1
- package/billing/plan-features.js +4 -3
- package/billing/plan-features.js.map +1 -1
- package/billing/useProviderKeys.d.ts +67 -0
- package/billing/useProviderKeys.d.ts.map +1 -0
- package/billing/useProviderKeys.js +61 -0
- package/billing/useProviderKeys.js.map +1 -0
- package/channel/AgentChannelsPanel.d.ts.map +1 -1
- package/channel/AgentChannelsPanel.js +11 -9
- package/channel/AgentChannelsPanel.js.map +1 -1
- package/channel/connect/ServingAppSection.js +1 -1
- package/channel/connect/ServingAppSection.js.map +1 -1
- package/channel-app/ChannelAppDetailPanel.d.ts +5 -0
- package/channel-app/ChannelAppDetailPanel.d.ts.map +1 -1
- package/channel-app/ChannelAppDetailPanel.js +22 -9
- package/channel-app/ChannelAppDetailPanel.js.map +1 -1
- package/channel-app/ChannelAppListPanel.d.ts +13 -4
- package/channel-app/ChannelAppListPanel.d.ts.map +1 -1
- package/channel-app/ChannelAppListPanel.js +5 -5
- package/channel-app/ChannelAppListPanel.js.map +1 -1
- package/channel-app/CreateChannelAppForm.js +1 -1
- package/channel-app/CreateChannelAppForm.js.map +1 -1
- package/channel-app/copy.d.ts +15 -0
- package/channel-app/copy.d.ts.map +1 -0
- package/channel-app/copy.js +15 -0
- package/channel-app/copy.js.map +1 -0
- package/channel-app/internal.d.ts +9 -0
- package/channel-app/internal.d.ts.map +1 -1
- package/channel-app/internal.js +9 -0
- package/channel-app/internal.js.map +1 -1
- package/channel-app/slackAppSetup.d.ts +3 -1
- package/channel-app/slackAppSetup.d.ts.map +1 -1
- package/channel-app/slackAppSetup.js +3 -1
- package/channel-app/slackAppSetup.js.map +1 -1
- package/channel-app/whatsappAppSetup.d.ts +3 -1
- package/channel-app/whatsappAppSetup.d.ts.map +1 -1
- package/channel-app/whatsappAppSetup.js +3 -1
- package/channel-app/whatsappAppSetup.js.map +1 -1
- package/composer/SessionComposer.d.ts.map +1 -1
- package/composer/SessionComposer.js +5 -9
- package/composer/SessionComposer.js.map +1 -1
- package/environment/EnvironmentVariableEditor.js +1 -1
- package/environment/EnvironmentVariableEditor.js.map +1 -1
- package/environment/index.d.ts +1 -1
- package/environment/index.d.ts.map +1 -1
- package/environment/index.js +1 -1
- package/environment/index.js.map +1 -1
- package/environment/systemEnvVars.d.ts +4 -63
- package/environment/systemEnvVars.d.ts.map +1 -1
- package/environment/systemEnvVars.js +21 -113
- package/environment/systemEnvVars.js.map +1 -1
- package/execution/RecalledMemoriesCard.js +1 -1
- package/iam-policy/OrgMembersPanel.js +1 -1
- package/iam-policy/OrgMembersPanel.js.map +1 -1
- package/iam-policy/useCheckPermission.d.ts +4 -1
- package/iam-policy/useCheckPermission.d.ts.map +1 -1
- package/iam-policy/useCheckPermission.js +4 -1
- package/iam-policy/useCheckPermission.js.map +1 -1
- package/iam-policy/useGrantableRoles.d.ts +1 -1
- package/iam-policy/useGrantableRoles.js +1 -1
- package/iam-policy/useRevokeOrgAccess.d.ts +10 -8
- package/iam-policy/useRevokeOrgAccess.d.ts.map +1 -1
- package/iam-policy/useRevokeOrgAccess.js +4 -4
- package/iam-policy/useRevokeOrgAccess.js.map +1 -1
- package/identity-account/AccountPreferencesPanel.d.ts +6 -0
- package/identity-account/AccountPreferencesPanel.d.ts.map +1 -1
- package/identity-account/AccountPreferencesPanel.js +33 -2
- package/identity-account/AccountPreferencesPanel.js.map +1 -1
- package/identity-account/useAccountExecutionDefaults.d.ts +1 -1
- package/identity-account/useAccountExecutionDefaults.d.ts.map +1 -1
- package/identity-account/useAccountExecutionDefaults.js +2 -3
- package/identity-account/useAccountExecutionDefaults.js.map +1 -1
- package/index.d.ts +3 -3
- package/index.d.ts.map +1 -1
- package/index.js +3 -3
- package/index.js.map +1 -1
- package/internal/UnknownPublicAddressNotice.d.ts +20 -0
- package/internal/UnknownPublicAddressNotice.d.ts.map +1 -0
- package/internal/UnknownPublicAddressNotice.js +19 -0
- package/internal/UnknownPublicAddressNotice.js.map +1 -0
- package/internal/features.js +2 -2
- package/internal/features.js.map +1 -1
- package/library/InstanceVisibilitySelector.d.ts +1 -1
- package/library/InstanceVisibilitySelector.d.ts.map +1 -1
- package/library/ResourceVisibilityControl.d.ts +6 -3
- package/library/ResourceVisibilityControl.d.ts.map +1 -1
- package/library/ResourceVisibilityControl.js +7 -4
- package/library/ResourceVisibilityControl.js.map +1 -1
- package/library/VisibilitySelector.d.ts +2 -2
- package/library/VisibilitySelector.d.ts.map +1 -1
- package/library/VisibilitySelector.js +1 -1
- package/licenses/LicenseIssueForm.js +1 -1
- package/licenses/LicenseIssueForm.js.map +1 -1
- package/licenses/license-format.d.ts +7 -5
- package/licenses/license-format.d.ts.map +1 -1
- package/licenses/license-format.js +1 -3
- package/licenses/license-format.js.map +1 -1
- package/mcp-server/McpServerConnectDialog.js +4 -5
- package/mcp-server/McpServerConnectDialog.js.map +1 -1
- package/mcp-server/McpServerDetailView.d.ts.map +1 -1
- package/mcp-server/McpServerDetailView.js +3 -6
- package/mcp-server/McpServerDetailView.js.map +1 -1
- package/mcp-server/McpServerPicker.d.ts.map +1 -1
- package/mcp-server/McpServerPicker.js +2 -6
- package/mcp-server/McpServerPicker.js.map +1 -1
- package/mcp-server/McpToolSelector.js +1 -1
- package/mcp-server/McpToolSelector.js.map +1 -1
- package/mcp-server/useMcpServerConnect.d.ts +14 -25
- package/mcp-server/useMcpServerConnect.d.ts.map +1 -1
- package/mcp-server/useMcpServerConnect.js +7 -19
- package/mcp-server/useMcpServerConnect.js.map +1 -1
- package/mcp-server/useMcpServerOAuthConnect.d.ts +1 -3
- package/mcp-server/useMcpServerOAuthConnect.d.ts.map +1 -1
- package/mcp-server/useMcpServerOAuthConnect.js +6 -19
- package/mcp-server/useMcpServerOAuthConnect.js.map +1 -1
- package/models/HarnessSelector.d.ts.map +1 -1
- package/models/HarnessSelector.js +1 -2
- package/models/HarnessSelector.js.map +1 -1
- package/models/ModelSelector.d.ts +1 -1
- package/models/ModelSelector.d.ts.map +1 -1
- package/models/ModelSelector.js +1 -7
- package/models/ModelSelector.js.map +1 -1
- package/models/harness.d.ts +10 -6
- package/models/harness.d.ts.map +1 -1
- package/models/harness.js +35 -28
- package/models/harness.js.map +1 -1
- package/models/index.d.ts +1 -1
- package/models/index.d.ts.map +1 -1
- package/models/index.js +1 -1
- package/models/index.js.map +1 -1
- package/organization/OrgPreferencesPanel.d.ts.map +1 -1
- package/organization/OrgPreferencesPanel.js +13 -1
- package/organization/OrgPreferencesPanel.js.map +1 -1
- package/package.json +5 -5
- package/plugin/useMcpServerReadiness.js +2 -2
- package/plugin/useMcpServerReadiness.js.map +1 -1
- package/provider-standing/ProviderStandingConsole.js +1 -1
- package/provider.d.ts +27 -1
- package/provider.d.ts.map +1 -1
- package/provider.js +3 -2
- package/provider.js.map +1 -1
- package/public-base-url-context.d.ts +35 -0
- package/public-base-url-context.d.ts.map +1 -0
- package/public-base-url-context.js +62 -0
- package/public-base-url-context.js.map +1 -0
- package/resource-workbench/components/SelectionCheckbox.js +1 -1
- package/resource-workbench/components/SelectionCheckbox.js.map +1 -1
- package/session/useLocalSessionWorker.d.ts +19 -3
- package/session/useLocalSessionWorker.d.ts.map +1 -1
- package/session/useLocalSessionWorker.js +37 -4
- package/session/useLocalSessionWorker.js.map +1 -1
- package/settings/ChannelAppsSection.d.ts +7 -0
- package/settings/ChannelAppsSection.d.ts.map +1 -1
- package/settings/ChannelAppsSection.js +15 -2
- package/settings/ChannelAppsSection.js.map +1 -1
- package/settings/ProviderKeysSection.d.ts +3 -0
- package/settings/ProviderKeysSection.d.ts.map +1 -0
- package/settings/ProviderKeysSection.js +3 -0
- package/settings/ProviderKeysSection.js.map +1 -0
- package/settings/index.d.ts +2 -0
- package/settings/index.d.ts.map +1 -1
- package/settings/index.js +1 -0
- package/settings/index.js.map +1 -1
- package/settings/settings-nav.d.ts.map +1 -1
- package/settings/settings-nav.js +2 -1
- package/settings/settings-nav.js.map +1 -1
- package/sharing/ShareAgentDialog.d.ts.map +1 -1
- package/sharing/ShareAgentDialog.js +12 -8
- package/sharing/ShareAgentDialog.js.map +1 -1
- package/sharing/useCanCreateAgentShare.d.ts +3 -1
- package/sharing/useCanCreateAgentShare.d.ts.map +1 -1
- package/sharing/useCanCreateAgentShare.js +5 -3
- package/sharing/useCanCreateAgentShare.js.map +1 -1
- package/sharing/useSaveAgentShare.d.ts +1 -1
- package/sharing/useSaveAgentShare.js +1 -1
- package/src/access/ManageAccessDialog.tsx +1 -1
- package/src/access/types.ts +1 -1
- package/src/billing/ChangePlanDialog.tsx +14 -2
- package/src/billing/ProviderKeysSection.tsx +324 -0
- package/src/billing/UpgradeNotice.tsx +1 -0
- package/src/billing/index.ts +9 -0
- package/src/billing/plan-features.ts +4 -3
- package/src/billing/useProviderKeys.ts +129 -0
- package/src/channel/AgentChannelsPanel.tsx +11 -9
- package/src/channel/connect/ServingAppSection.tsx +1 -1
- package/src/channel-app/ChannelAppDetailPanel.tsx +214 -176
- package/src/channel-app/ChannelAppListPanel.tsx +14 -4
- package/src/channel-app/CreateChannelAppForm.tsx +0 -1
- package/src/channel-app/copy.ts +16 -0
- package/src/channel-app/internal.tsx +21 -0
- package/src/channel-app/slackAppSetup.ts +3 -1
- package/src/channel-app/whatsappAppSetup.ts +3 -1
- package/src/composer/SessionComposer.tsx +5 -14
- package/src/environment/EnvironmentVariableEditor.tsx +1 -1
- package/src/environment/index.ts +1 -7
- package/src/environment/systemEnvVars.ts +21 -133
- package/src/execution/RecalledMemoriesCard.tsx +1 -1
- package/src/iam-policy/OrgMembersPanel.tsx +3 -1
- package/src/iam-policy/useCheckPermission.ts +4 -1
- package/src/iam-policy/useGrantableRoles.ts +1 -1
- package/src/iam-policy/useRevokeOrgAccess.ts +10 -8
- package/src/identity-account/AccountPreferencesPanel.tsx +56 -9
- package/src/identity-account/useAccountExecutionDefaults.ts +2 -5
- package/src/index.ts +9 -5
- package/src/internal/UnknownPublicAddressNotice.tsx +31 -0
- package/src/internal/features.ts +2 -2
- package/src/library/InstanceVisibilitySelector.tsx +1 -1
- package/src/library/ResourceVisibilityControl.tsx +7 -4
- package/src/library/VisibilitySelector.tsx +2 -2
- package/src/licenses/LicenseIssueForm.tsx +1 -1
- package/src/licenses/license-format.ts +11 -7
- package/src/mcp-server/McpServerConnectDialog.tsx +4 -6
- package/src/mcp-server/McpServerDetailView.tsx +3 -6
- package/src/mcp-server/McpServerPicker.tsx +2 -12
- package/src/mcp-server/McpToolSelector.tsx +1 -1
- package/src/mcp-server/useMcpServerConnect.ts +14 -33
- package/src/mcp-server/useMcpServerOAuthConnect.ts +7 -23
- package/src/models/HarnessSelector.tsx +1 -3
- package/src/models/ModelSelector.tsx +2 -7
- package/src/models/harness.ts +41 -39
- package/src/models/index.ts +1 -1
- package/src/organization/OrgPreferencesPanel.tsx +19 -1
- package/src/plugin/useMcpServerReadiness.ts +2 -2
- package/src/provider-standing/ProviderStandingConsole.tsx +1 -1
- package/src/provider.tsx +56 -26
- package/src/public-base-url-context.ts +70 -0
- package/src/resource-workbench/components/SelectionCheckbox.tsx +1 -1
- package/src/session/useLocalSessionWorker.ts +35 -4
- package/src/settings/ChannelAppsSection.tsx +19 -2
- package/src/settings/ProviderKeysSection.tsx +4 -0
- package/src/settings/index.ts +2 -0
- package/src/settings/settings-nav.ts +2 -0
- package/src/sharing/ShareAgentDialog.tsx +30 -14
- package/src/sharing/useCanCreateAgentShare.ts +6 -4
- package/src/sharing/useSaveAgentShare.ts +1 -1
- package/src/styles.css +14 -4
- package/src/workflow/WorkflowTaskApprovalSummary.tsx +14 -7
- package/src/workflow/inspector/tabs/BranchesTab.tsx +2 -2
- package/src/workflow/inspector/tabs/CatchTab.tsx +1 -1
- package/src/workflow/inspector/tabs/IterationTab.tsx +1 -1
- package/src/workflow/instance/WorkflowInstanceDetailPanel.tsx +7 -6
- package/src/workflow/task-detail/task-approval.ts +20 -13
- package/styles.css +1 -1
- package/workflow/WorkflowTaskApprovalSummary.d.ts +7 -4
- package/workflow/WorkflowTaskApprovalSummary.d.ts.map +1 -1
- package/workflow/WorkflowTaskApprovalSummary.js +8 -3
- package/workflow/WorkflowTaskApprovalSummary.js.map +1 -1
- package/workflow/inspector/tabs/BranchesTab.js +1 -1
- package/workflow/inspector/tabs/BranchesTab.js.map +1 -1
- package/workflow/inspector/tabs/CatchTab.js +1 -1
- package/workflow/inspector/tabs/CatchTab.js.map +1 -1
- package/workflow/inspector/tabs/IterationTab.js +1 -1
- package/workflow/inspector/tabs/IterationTab.js.map +1 -1
- package/workflow/instance/WorkflowInstanceDetailPanel.d.ts.map +1 -1
- package/workflow/instance/WorkflowInstanceDetailPanel.js +6 -5
- package/workflow/instance/WorkflowInstanceDetailPanel.js.map +1 -1
- package/workflow/task-detail/task-approval.d.ts +13 -11
- package/workflow/task-detail/task-approval.d.ts.map +1 -1
- package/workflow/task-detail/task-approval.js +8 -4
- package/workflow/task-detail/task-approval.js.map +1 -1
package/src/environment/index.ts
CHANGED
|
@@ -41,13 +41,7 @@ export type {
|
|
|
41
41
|
SessionEnvPoolInput,
|
|
42
42
|
UseSessionEnvPoolReturn,
|
|
43
43
|
} from "./useSessionEnvPool.js";
|
|
44
|
-
export {
|
|
45
|
-
SYSTEM_ENV_VAR_KEYS,
|
|
46
|
-
toGrpcAddress,
|
|
47
|
-
buildSystemEnvVars,
|
|
48
|
-
resolveSystemEnvVarValues,
|
|
49
|
-
resolveDeclaredSystemEnvVars,
|
|
50
|
-
} from "./systemEnvVars.js";
|
|
44
|
+
export { SYSTEM_ENV_VAR_KEYS } from "./systemEnvVars.js";
|
|
51
45
|
export { EnvironmentPicker } from "./EnvironmentPicker.js";
|
|
52
46
|
export type { EnvironmentPickerProps } from "./EnvironmentPicker.js";
|
|
53
47
|
export { useToolCredentialsReadiness } from "./useToolCredentialsReadiness.js";
|
|
@@ -1,143 +1,31 @@
|
|
|
1
|
-
import type { EnvVarInput, Stigmer } from "@stigmer/sdk";
|
|
2
|
-
|
|
3
1
|
// ---------------------------------------------------------------------------
|
|
4
2
|
// Well-known Stigmer platform environment variable keys
|
|
5
3
|
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
4
|
+
// A platform value comes from the component that knows it, fills only a key
|
|
5
|
+
// that is still missing, and reaches only a server that declares it
|
|
6
|
+
// (stigmer/stigmer#1446). The page is not that component for any key, so
|
|
7
|
+
// this SDK supplies none: a value it wrote into a run's runtime env would
|
|
8
|
+
// sit in the top merge layer, above every value a user saved, and a run
|
|
9
|
+
// whose agent declares no env would carry it into the agent's shell.
|
|
10
|
+
//
|
|
11
|
+
// STIGMER_SERVER_ADDRESS is the one key the platform fills. The runner
|
|
12
|
+
// writes it for a server that declares it and holds no value: from the
|
|
13
|
+
// server's public address, which the server hands every sandbox it
|
|
14
|
+
// provisions, or for a stdio child from the endpoint the runner dials
|
|
15
|
+
// itself (backend/services/runner, the platform-server-address module).
|
|
16
|
+
//
|
|
17
|
+
// STIGMER_API_KEY is not a platform key. A server that calls the Stigmer
|
|
18
|
+
// API declares it like any other secret, and its user saves an API key for
|
|
19
|
+
// it; nothing hands a user-defined server the signed-in user's bearer.
|
|
11
20
|
// ---------------------------------------------------------------------------
|
|
12
21
|
|
|
13
|
-
const STIGMER_SERVER_ADDRESS = "STIGMER_SERVER_ADDRESS";
|
|
14
|
-
const STIGMER_API_KEY = "STIGMER_API_KEY";
|
|
15
|
-
|
|
16
22
|
/**
|
|
17
|
-
* Environment variable keys
|
|
18
|
-
*
|
|
23
|
+
* Environment variable keys the platform fills itself, so the setup hooks
|
|
24
|
+
* never prompt a user for them and the credential forms never ask for them.
|
|
19
25
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* values into runtime env at submit time.
|
|
23
|
-
*
|
|
24
|
-
* Platform builders who manage setup hooks directly can use this
|
|
25
|
-
* set to extend their own `poolKeys`.
|
|
26
|
+
* Platform builders who manage setup hooks directly can use this set to
|
|
27
|
+
* extend their own `poolKeys`.
|
|
26
28
|
*/
|
|
27
29
|
export const SYSTEM_ENV_VAR_KEYS: ReadonlySet<string> = new Set([
|
|
28
|
-
STIGMER_SERVER_ADDRESS,
|
|
29
|
-
STIGMER_API_KEY,
|
|
30
|
+
"STIGMER_SERVER_ADDRESS",
|
|
30
31
|
]);
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Convert an HTTP(S) base URL to a gRPC host:port address.
|
|
34
|
-
*
|
|
35
|
-
* The Stigmer server serves both gRPC and gRPC-Web on the same
|
|
36
|
-
* endpoint, so stripping the protocol and extracting host:port
|
|
37
|
-
* produces a valid gRPC dial target.
|
|
38
|
-
*
|
|
39
|
-
* @example
|
|
40
|
-
* ```ts
|
|
41
|
-
* toGrpcAddress("http://localhost:7234") // "localhost:7234"
|
|
42
|
-
* toGrpcAddress("https://api.stigmer.ai") // "api.stigmer.ai:443"
|
|
43
|
-
* toGrpcAddress("https://api.stigmer.ai:8443") // "api.stigmer.ai:8443"
|
|
44
|
-
* ```
|
|
45
|
-
*/
|
|
46
|
-
export function toGrpcAddress(httpUrl: string): string {
|
|
47
|
-
try {
|
|
48
|
-
const url = new URL(httpUrl);
|
|
49
|
-
const host = url.hostname;
|
|
50
|
-
const port =
|
|
51
|
-
url.port || (url.protocol === "https:" ? "443" : "80");
|
|
52
|
-
return `${host}:${port}`;
|
|
53
|
-
} catch {
|
|
54
|
-
return httpUrl;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Build system env var entries from raw connection parameters.
|
|
60
|
-
*
|
|
61
|
-
* Pure function — no side effects, no async. Suitable for unit
|
|
62
|
-
* testing without a live Stigmer client.
|
|
63
|
-
*
|
|
64
|
-
* @param baseUrl - The Stigmer client's base URL (HTTP).
|
|
65
|
-
* @param credential - Current auth credential, or `null` for
|
|
66
|
-
* unauthenticated (OSS) backends. When `null`, a placeholder
|
|
67
|
-
* value is used so the MCP server env var is always populated.
|
|
68
|
-
*/
|
|
69
|
-
export function buildSystemEnvVars(
|
|
70
|
-
baseUrl: string,
|
|
71
|
-
credential: string | null,
|
|
72
|
-
): Record<string, EnvVarInput> {
|
|
73
|
-
return {
|
|
74
|
-
[STIGMER_SERVER_ADDRESS]: {
|
|
75
|
-
value: toGrpcAddress(baseUrl),
|
|
76
|
-
isSecret: false,
|
|
77
|
-
description:
|
|
78
|
-
"Auto-resolved from the current Stigmer connection.",
|
|
79
|
-
},
|
|
80
|
-
[STIGMER_API_KEY]: {
|
|
81
|
-
value: credential || "unused",
|
|
82
|
-
isSecret: true,
|
|
83
|
-
description:
|
|
84
|
-
"Auto-resolved from the current Stigmer auth context.",
|
|
85
|
-
},
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Resolve system env var values from a live {@link Stigmer} client.
|
|
91
|
-
*
|
|
92
|
-
* Calls {@link Stigmer.getAuthCredential} to obtain the current
|
|
93
|
-
* credential, then delegates to {@link buildSystemEnvVars}.
|
|
94
|
-
*
|
|
95
|
-
* Intended for use at session submit time — the returned values
|
|
96
|
-
* are injected into `runtimeEnv` at the **lowest priority** so
|
|
97
|
-
* any user-provided values (personal env, manual secrets) win.
|
|
98
|
-
*/
|
|
99
|
-
export async function resolveSystemEnvVarValues(
|
|
100
|
-
stigmer: Stigmer,
|
|
101
|
-
): Promise<Record<string, EnvVarInput>> {
|
|
102
|
-
const credential = await stigmer.getAuthCredential();
|
|
103
|
-
return buildSystemEnvVars(stigmer.baseUrl, credential);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Resolve only the system env vars that the target resource actually
|
|
108
|
-
* declares in its environment specification.
|
|
109
|
-
*
|
|
110
|
-
* System vars (`STIGMER_SERVER_ADDRESS`, `STIGMER_API_KEY`) should
|
|
111
|
-
* only be injected when the resource needs them — blindly injecting
|
|
112
|
-
* them causes `runtime_env` to be non-empty on the wire, which
|
|
113
|
-
* changes the backend's missing-credential tolerance semantics.
|
|
114
|
-
*
|
|
115
|
-
* @param stigmer - Live Stigmer client for credential resolution.
|
|
116
|
-
* @param declaredEnvKeys - The set of env var keys the target
|
|
117
|
-
* resource declares (e.g., `Object.keys(mcpServer.spec.env)`).
|
|
118
|
-
* Only system vars whose keys appear here are included.
|
|
119
|
-
* @returns Filtered system env vars (may be empty).
|
|
120
|
-
*/
|
|
121
|
-
export async function resolveDeclaredSystemEnvVars(
|
|
122
|
-
stigmer: Stigmer,
|
|
123
|
-
declaredEnvKeys: ReadonlySet<string> | readonly string[],
|
|
124
|
-
): Promise<Record<string, EnvVarInput>> {
|
|
125
|
-
const keys =
|
|
126
|
-
declaredEnvKeys instanceof Set
|
|
127
|
-
? declaredEnvKeys
|
|
128
|
-
: new Set(declaredEnvKeys);
|
|
129
|
-
|
|
130
|
-
const hasDeclared = [...SYSTEM_ENV_VAR_KEYS].some((k) => keys.has(k));
|
|
131
|
-
if (!hasDeclared) {
|
|
132
|
-
return {};
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const all = await resolveSystemEnvVarValues(stigmer);
|
|
136
|
-
const filtered: Record<string, EnvVarInput> = {};
|
|
137
|
-
for (const [key, value] of Object.entries(all)) {
|
|
138
|
-
if (keys.has(key)) {
|
|
139
|
-
filtered[key] = value;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
return filtered;
|
|
143
|
-
}
|
|
@@ -90,7 +90,7 @@ export const RecalledMemoriesCard = memo(function RecalledMemoriesCard({
|
|
|
90
90
|
onClick={() => setExpanded((prev) => !prev)}
|
|
91
91
|
className={cn(
|
|
92
92
|
"stg:flex stg:w-full stg:items-center stg:gap-3 stg:px-3 stg:py-2 stg:text-left",
|
|
93
|
-
"stg:text-xs stg:text-muted-foreground hover:
|
|
93
|
+
"stg:text-xs stg:text-muted-foreground stg:hover:text-foreground",
|
|
94
94
|
)}
|
|
95
95
|
>
|
|
96
96
|
<MemoryIcon />
|
|
@@ -496,7 +496,9 @@ function RemoveCopy({
|
|
|
496
496
|
case "member":
|
|
497
497
|
return (
|
|
498
498
|
<>
|
|
499
|
-
Remove {name} from this organization?
|
|
499
|
+
Remove {name} from this organization? They lose access to everything
|
|
500
|
+
in it, including what was shared with them and their teams. What
|
|
501
|
+
they created stays with the organization.
|
|
500
502
|
</>
|
|
501
503
|
);
|
|
502
504
|
case "productUser":
|
|
@@ -69,7 +69,10 @@ interface SettledCheck {
|
|
|
69
69
|
* `false` (so operator-only navigation never appears where the seat
|
|
70
70
|
* does not exist), `can_grant_access` on a resource the edition does not
|
|
71
71
|
* share per person is `false` (open source grants roles on organizations
|
|
72
|
-
* only), and everything else is the edition's authorizer's answer.
|
|
72
|
+
* only), and everything else is the edition's authorizer's answer. So a
|
|
73
|
+
* control that changes who reaches a resource (its visibility, a share, a
|
|
74
|
+
* channel) asks `can_manage_audience`, never `can_grant_access`: the owner
|
|
75
|
+
* holds it in every edition. By
|
|
73
76
|
* default the hook *fails open* while the check is in flight or when the
|
|
74
77
|
* RPC fails, so a transient error never hides a control the server would
|
|
75
78
|
* honor. Pass `{ fail: "closed" }` for surfaces that must stay hidden
|
|
@@ -26,7 +26,7 @@ export interface UseGrantableRolesReturn {
|
|
|
26
26
|
* @example
|
|
27
27
|
* ```tsx
|
|
28
28
|
* const { roles, hasRoles } = useGrantableRoles(ApiResourceKind.agent);
|
|
29
|
-
* // roles = [IamRole.owner, IamRole.viewer]
|
|
29
|
+
* // roles = [IamRole.owner, IamRole.editor, IamRole.viewer]
|
|
30
30
|
* // hasRoles = true
|
|
31
31
|
* ```
|
|
32
32
|
*/
|
|
@@ -9,11 +9,13 @@ import { toError } from "../internal/toError.js";
|
|
|
9
9
|
/** Return value of {@link useRevokeOrgAccess}. */
|
|
10
10
|
export interface UseRevokeOrgAccessReturn {
|
|
11
11
|
/**
|
|
12
|
-
* Remove
|
|
12
|
+
* Remove a person from an organization.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* Revokes their roles on the organization and everything they hold on
|
|
15
|
+
* its resources: what was shared with them (agents, environments,
|
|
16
|
+
* sessions and the rest) and their team memberships, in a single
|
|
17
|
+
* operation. What they created stays with the organization; it is
|
|
18
|
+
* theirs again only if they are invited back.
|
|
17
19
|
*/
|
|
18
20
|
readonly revoke: (accountId: string, orgId: string) => Promise<void>;
|
|
19
21
|
/** `true` while the revoke request is in flight. */
|
|
@@ -28,10 +30,10 @@ export interface UseRevokeOrgAccessReturn {
|
|
|
28
30
|
* Behavior hook that wraps `iamPolicy.revokeOrgAccess()` with
|
|
29
31
|
* loading/error state.
|
|
30
32
|
*
|
|
31
|
-
* Removes
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* operation.
|
|
33
|
+
* Removes a person from an organization: their roles on it, what was
|
|
34
|
+
* shared with them on its resources and their team memberships. From
|
|
35
|
+
* then on they reach nothing in the organization; what they created
|
|
36
|
+
* stays with it. This is the "remove member from org" operation.
|
|
35
37
|
*
|
|
36
38
|
* @example
|
|
37
39
|
* ```tsx
|
|
@@ -15,6 +15,7 @@ import type { IdentityAccount } from "@stigmer/protos/ai/stigmer/iam/identityacc
|
|
|
15
15
|
import { useMyIdentityAccount } from "./useMyIdentityAccount.js";
|
|
16
16
|
import { useUpdateIdentityAccount } from "./useUpdateIdentityAccount.js";
|
|
17
17
|
import { useModelRegistry } from "../models/index.js";
|
|
18
|
+
import { useServerInfo } from "../server-info.js";
|
|
18
19
|
import { HARNESS_META, type HarnessOption } from "../models/harness.js";
|
|
19
20
|
import { MemoryEnabledRow } from "../internal/MemoryEnabledRow.js";
|
|
20
21
|
import { StandingContextField } from "../internal/StandingContextField.js";
|
|
@@ -49,6 +50,12 @@ export interface AccountPreferencesPanelProps {
|
|
|
49
50
|
* answer with. A server that cannot answer surfaces its error through the
|
|
50
51
|
* fetch-error state below, never a hidden branch.
|
|
51
52
|
*
|
|
53
|
+
* The one posture question it does ask is about memory. The person's own
|
|
54
|
+
* memory switch is honoured only by a server that authenticates its
|
|
55
|
+
* callers; on a server that trusts every request (the single-operator
|
|
56
|
+
* laptop), memory is the organization's switch alone, so the panel says
|
|
57
|
+
* that in the switch's place rather than offering one that does nothing.
|
|
58
|
+
*
|
|
52
59
|
* All visual properties flow through `--stgm-*` design tokens. Zero
|
|
53
60
|
* dependencies on Console routing, auth context, or layout — platform
|
|
54
61
|
* builders can embed it directly:
|
|
@@ -86,6 +93,8 @@ export function AccountPreferencesPanel({
|
|
|
86
93
|
error: memoryFlagError,
|
|
87
94
|
} = useUpdateIdentityAccount();
|
|
88
95
|
|
|
96
|
+
const memoryGovernance = useMemoryGovernance();
|
|
97
|
+
|
|
89
98
|
const [standingContext, setStandingContext] = useState("");
|
|
90
99
|
const [defaultHarness, setDefaultHarness] = useState("");
|
|
91
100
|
const [defaultNativeModel, setDefaultNativeModel] = useState("");
|
|
@@ -377,14 +386,17 @@ export function AccountPreferencesPanel({
|
|
|
377
386
|
</div>
|
|
378
387
|
</div>
|
|
379
388
|
|
|
380
|
-
<
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
389
|
+
{memoryGovernance === "organization" && <OrganizationGovernedMemory />}
|
|
390
|
+
{memoryGovernance === "person" && (
|
|
391
|
+
<MemoryEnabledRow
|
|
392
|
+
id={`${baseId}-memory-enabled`}
|
|
393
|
+
checked={account.spec?.preferences?.memoryEnabled ?? false}
|
|
394
|
+
onToggle={(next) => void handleMemoryToggle(next)}
|
|
395
|
+
saving={isSavingMemoryFlag}
|
|
396
|
+
error={memoryFlagError}
|
|
397
|
+
helperText="When on, agents may propose facts to remember about you; only facts you confirm are stored. Confirmed memories are shared with your future sessions and appear on those executions' records; once you have many, each conversation recalls the most relevant ones, shown on the execution. Requires your organization to have memory enabled. Changes apply immediately."
|
|
398
|
+
/>
|
|
399
|
+
)}
|
|
388
400
|
|
|
389
401
|
{updateError && (
|
|
390
402
|
<p className="stg:text-destructive stg:text-[0.65rem]" role="alert">
|
|
@@ -494,7 +506,7 @@ function HarnessOptionRow({
|
|
|
494
506
|
disabled={disabled}
|
|
495
507
|
aria-labelledby={titleId}
|
|
496
508
|
aria-describedby={descriptionId}
|
|
497
|
-
className="stg:mt-0.5 stg:
|
|
509
|
+
className="stg:mt-0.5 stg:focus-visible:outline-none stg:focus-visible:ring-1 stg:focus-visible:ring-ring"
|
|
498
510
|
/>
|
|
499
511
|
<span className="stg:min-w-0 stg:flex-1">
|
|
500
512
|
<span
|
|
@@ -584,3 +596,38 @@ function DefaultModelSelect({
|
|
|
584
596
|
</div>
|
|
585
597
|
);
|
|
586
598
|
}
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* Who decides memory on the connected server, for the memory row.
|
|
602
|
+
*
|
|
603
|
+
* - `"person"`: the person's own switch counts (a server that authenticates
|
|
604
|
+
* its callers, one too old to report its posture, or one whose answer
|
|
605
|
+
* failed: an unknown posture offers the control and lets the server
|
|
606
|
+
* decide, as `authentication_required`'s contract says).
|
|
607
|
+
* - `"organization"`: the server trusts every request, so its one operator
|
|
608
|
+
* decides memory through the organization's switch alone.
|
|
609
|
+
* - `null`: the server has not answered yet, so the row renders nothing
|
|
610
|
+
* rather than a switch that flashes and disappears.
|
|
611
|
+
*/
|
|
612
|
+
function useMemoryGovernance(): "person" | "organization" | null {
|
|
613
|
+
const { serverInfo, error } = useServerInfo();
|
|
614
|
+
if (serverInfo !== null) {
|
|
615
|
+
return serverInfo.authenticationRequired === false ? "organization" : "person";
|
|
616
|
+
}
|
|
617
|
+
return error !== null ? "person" : null;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/** The memory row on a server where the organization's switch alone decides. */
|
|
621
|
+
function OrganizationGovernedMemory() {
|
|
622
|
+
return (
|
|
623
|
+
<div className="stg:space-y-1">
|
|
624
|
+
<span className="stg:block stg:text-xs stg:font-medium stg:text-foreground">
|
|
625
|
+
Memory
|
|
626
|
+
</span>
|
|
627
|
+
<p className="stg:text-[0.65rem] stg:leading-snug stg:text-muted-foreground">
|
|
628
|
+
On this server, memory follows your organization's setting. Turn it
|
|
629
|
+
on or off in the organization's preferences.
|
|
630
|
+
</p>
|
|
631
|
+
</div>
|
|
632
|
+
);
|
|
633
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useMemo } from "react";
|
|
4
4
|
import { useMyIdentityAccount } from "./useMyIdentityAccount.js";
|
|
5
|
-
import type
|
|
5
|
+
import { isHarnessOption, type HarnessOption } from "../models/harness.js";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* The current user's account-level execution defaults, shaped for the
|
|
@@ -57,10 +57,7 @@ export function useAccountExecutionDefaults(): AccountExecutionDefaults | undefi
|
|
|
57
57
|
// The proto validates default_harness to the shipped set, but a client
|
|
58
58
|
// must not trust persisted data it did not write — unknown values are
|
|
59
59
|
// treated as undeclared.
|
|
60
|
-
const harness =
|
|
61
|
-
prefs.defaultHarness === "native" || prefs.defaultHarness === "cursor"
|
|
62
|
-
? (prefs.defaultHarness satisfies HarnessOption)
|
|
63
|
-
: undefined;
|
|
60
|
+
const harness = isHarnessOption(prefs.defaultHarness) ? prefs.defaultHarness : undefined;
|
|
64
61
|
const nativeModel = prefs.defaultNativeModel || undefined;
|
|
65
62
|
const cursorModel = prefs.defaultCursorModel || undefined;
|
|
66
63
|
// Only a declared `true` travels — an unset bool is "no preference",
|
package/src/index.ts
CHANGED
|
@@ -948,7 +948,7 @@ export type {
|
|
|
948
948
|
UseUpdateScheduleSpecReturn,
|
|
949
949
|
} from "./schedule/index.js";
|
|
950
950
|
|
|
951
|
-
// Environment — data hooks, list hook, personal convenience hook, secret reveal, variable management, env var form,
|
|
951
|
+
// Environment — data hooks, list hook, personal convenience hook, secret reveal, variable management, env var form, the platform-filled key set, and styled components
|
|
952
952
|
export {
|
|
953
953
|
useEnvironment,
|
|
954
954
|
useEnvironmentList,
|
|
@@ -964,10 +964,6 @@ export {
|
|
|
964
964
|
EnvVarForm,
|
|
965
965
|
useSessionEnvPool,
|
|
966
966
|
SYSTEM_ENV_VAR_KEYS,
|
|
967
|
-
toGrpcAddress,
|
|
968
|
-
buildSystemEnvVars,
|
|
969
|
-
resolveSystemEnvVarValues,
|
|
970
|
-
resolveDeclaredSystemEnvVars,
|
|
971
967
|
EnvironmentPicker,
|
|
972
968
|
useToolCredentialsReadiness,
|
|
973
969
|
} from "./environment/index.js";
|
|
@@ -1164,6 +1160,9 @@ export {
|
|
|
1164
1160
|
useSubscription,
|
|
1165
1161
|
useEntitlements,
|
|
1166
1162
|
usePeriodEstimate,
|
|
1163
|
+
useProviderKeys,
|
|
1164
|
+
useProviderKeyActions,
|
|
1165
|
+
ProviderKeysSection,
|
|
1167
1166
|
useChangePlan,
|
|
1168
1167
|
useCancelSubscription,
|
|
1169
1168
|
useCreatePaymentMethodSetupSession,
|
|
@@ -1206,6 +1205,11 @@ export type {
|
|
|
1206
1205
|
UseEntitlementsReturn,
|
|
1207
1206
|
UsePeriodEstimateOptions,
|
|
1208
1207
|
UsePeriodEstimateReturn,
|
|
1208
|
+
ProviderKeyProvider,
|
|
1209
|
+
UseProviderKeysOptions,
|
|
1210
|
+
UseProviderKeysReturn,
|
|
1211
|
+
UseProviderKeyActionsReturn,
|
|
1212
|
+
ProviderKeysSectionProps,
|
|
1209
1213
|
UseChangePlanReturn,
|
|
1210
1214
|
UseCancelSubscriptionReturn,
|
|
1211
1215
|
UseCreatePaymentMethodSetupSessionReturn,
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
/** Props for {@link UnknownPublicAddressNotice}. */
|
|
4
|
+
export interface UnknownPublicAddressNoticeProps {
|
|
5
|
+
/** What cannot be shown, as it reads mid-sentence ("the callback URL"). */
|
|
6
|
+
readonly subject: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Shown in place of a copyable URL or snippet when the server's public
|
|
11
|
+
* address is unknown (`usePublicBaseUrl` answered `null`): the client talks
|
|
12
|
+
* to the server through a relative `baseUrl` and the host named no
|
|
13
|
+
* `publicBaseUrl`. One sentence, shared by every copy surface, so a user is
|
|
14
|
+
* told plainly why there is nothing to copy instead of being offered an
|
|
15
|
+
* address Slack, Meta or a backend cannot call.
|
|
16
|
+
*
|
|
17
|
+
* The surface keeps its own label above the notice, the shape the channel
|
|
18
|
+
* app panel already uses for a verify token it can no longer show. The
|
|
19
|
+
* reader is the host's user, not its developer, so the copy names no prop
|
|
20
|
+
* or configuration.
|
|
21
|
+
*/
|
|
22
|
+
export function UnknownPublicAddressNotice({
|
|
23
|
+
subject,
|
|
24
|
+
}: UnknownPublicAddressNoticeProps) {
|
|
25
|
+
return (
|
|
26
|
+
<p className="stg:text-[0.65rem] stg:text-muted-foreground">
|
|
27
|
+
This app doesn't know your Stigmer server's public address, so
|
|
28
|
+
it can't show {subject}.
|
|
29
|
+
</p>
|
|
30
|
+
);
|
|
31
|
+
}
|
package/src/internal/features.ts
CHANGED
|
@@ -23,7 +23,7 @@ export const FEATURE_COPY: Readonly<
|
|
|
23
23
|
},
|
|
24
24
|
[Feature.byo_provider_keys]: {
|
|
25
25
|
label: "Bring your own provider keys",
|
|
26
|
-
description: "
|
|
26
|
+
description: "Run agents on your own Anthropic and OpenAI keys, with no Stigmer commission on those tokens.",
|
|
27
27
|
},
|
|
28
28
|
[Feature.channels]: {
|
|
29
29
|
label: "Channels",
|
|
@@ -31,7 +31,7 @@ export const FEATURE_COPY: Readonly<
|
|
|
31
31
|
},
|
|
32
32
|
[Feature.sharing]: {
|
|
33
33
|
label: "Sharing",
|
|
34
|
-
description: "Share agents with
|
|
34
|
+
description: "Share agents through hosted links, with your organization or with anyone who has the link.",
|
|
35
35
|
},
|
|
36
36
|
[Feature.teams]: {
|
|
37
37
|
label: "Teams",
|
|
@@ -26,7 +26,7 @@ export interface InstanceVisibilitySelectorProps {
|
|
|
26
26
|
readonly mode?: VisibilitySelectorMode;
|
|
27
27
|
/** Shows a spinner/disabled state while the RPC is in flight. */
|
|
28
28
|
readonly isPending?: boolean;
|
|
29
|
-
/** Disables all interaction (e.g., when the user lacks
|
|
29
|
+
/** Disables all interaction (e.g., when the user lacks can_manage_audience). */
|
|
30
30
|
readonly disabled?: boolean;
|
|
31
31
|
/** Additional CSS classes applied to the root element. */
|
|
32
32
|
readonly className?: string;
|
|
@@ -71,10 +71,13 @@ export interface ResourceVisibilityControlProps {
|
|
|
71
71
|
*
|
|
72
72
|
* Behavior:
|
|
73
73
|
* - Always renders a legible state: a read-only {@link VisibilityBadge}
|
|
74
|
-
* is shown to
|
|
75
|
-
* is in flight — never a silent blank.
|
|
74
|
+
* is shown to anyone without `can_manage_audience` and while the
|
|
75
|
+
* permission check is in flight — never a silent blank.
|
|
76
76
|
* - Upgrades to the interactive {@link VisibilitySelector} for users with
|
|
77
|
-
* `
|
|
77
|
+
* `can_manage_audience`, the server's bar on every `updateVisibility`:
|
|
78
|
+
* visibility decides who reaches the resource, so an editor, who may
|
|
79
|
+
* change the definition, sees the badge. Persists changes via
|
|
80
|
+
* {@link useUpdateVisibility} and invokes
|
|
78
81
|
* {@link ResourceVisibilityControlProps.onChanged} on success.
|
|
79
82
|
*
|
|
80
83
|
* Offered levels are kind- and context-aware (`visibilityLevels.ts`):
|
|
@@ -166,7 +169,7 @@ export function ResourceVisibilityControl({
|
|
|
166
169
|
return (
|
|
167
170
|
<PermissionGate
|
|
168
171
|
resource={{ kind: FGA_KIND[kind], id: resourceId }}
|
|
169
|
-
relation="
|
|
172
|
+
relation="can_manage_audience"
|
|
170
173
|
fallback={badge}
|
|
171
174
|
loading={badge}
|
|
172
175
|
>
|
|
@@ -54,7 +54,7 @@ export interface VisibilitySelectorProps {
|
|
|
54
54
|
readonly mode?: VisibilitySelectorMode;
|
|
55
55
|
/** Shows a spinner/disabled state while the RPC is in flight. */
|
|
56
56
|
readonly isPending?: boolean;
|
|
57
|
-
/** Disables all interaction (e.g., when the user lacks
|
|
57
|
+
/** Disables all interaction (e.g., when the user lacks can_manage_audience). */
|
|
58
58
|
readonly disabled?: boolean;
|
|
59
59
|
/** Accessible name for the control. Defaults to "Resource visibility". */
|
|
60
60
|
readonly ariaLabel?: string;
|
|
@@ -444,7 +444,7 @@ export interface VisibilityBadgeProps {
|
|
|
444
444
|
* for a row from before its retirement).
|
|
445
445
|
*
|
|
446
446
|
* Rendered wherever the interactive {@link VisibilitySelector} is not
|
|
447
|
-
* available — for
|
|
447
|
+
* available — for anyone who lacks `can_manage_audience`, and while a permission check
|
|
448
448
|
* is in flight — so a resource's visibility is always legible rather than
|
|
449
449
|
* silently blank. Shares the chip styling with the selector trigger so the
|
|
450
450
|
* read-only and editable states are visually consistent.
|
|
@@ -71,7 +71,7 @@ type CustomerMode = "existing" | "new";
|
|
|
71
71
|
* browser-blue control inside its brand.
|
|
72
72
|
*/
|
|
73
73
|
const NATIVE_CONTROL =
|
|
74
|
-
"stg:size-3.5 stg:shrink-0 stg:cursor-pointer stg:
|
|
74
|
+
"stg:size-3.5 stg:shrink-0 stg:cursor-pointer stg:focus-visible:outline-none stg:focus-visible:ring-2 stg:focus-visible:ring-ring stg:focus-visible:ring-offset-1";
|
|
75
75
|
|
|
76
76
|
const TERM_PRESET_HINT: Readonly<Record<IssuableTerm, string>> = {
|
|
77
77
|
[LicenseTerm.trial]: "30 days",
|
|
@@ -27,11 +27,17 @@ export type IssuableTerm = LicenseTerm.trial | LicenseTerm.paid;
|
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Features a Cloud plan sells but a license never carries: they tier the
|
|
30
|
-
* hosted runtime, and
|
|
31
|
-
*
|
|
32
|
-
* control.
|
|
30
|
+
* Cloud's hosted runtime, and on a self-hosted deployment the edition
|
|
31
|
+
* decides whether they exist, never a license, so offering one on a
|
|
32
|
+
* license would sell a capability the license does not control. A license
|
|
33
|
+
* issued before a value joined this list may still carry it; the console
|
|
34
|
+
* shows it nowhere.
|
|
33
35
|
*/
|
|
34
|
-
export type PlanOnlyFeature =
|
|
36
|
+
export type PlanOnlyFeature =
|
|
37
|
+
| Feature.channels
|
|
38
|
+
| Feature.sharing
|
|
39
|
+
| Feature.teams
|
|
40
|
+
| Feature.managed_organizations;
|
|
35
41
|
|
|
36
42
|
/**
|
|
37
43
|
* Features the contract names but nothing gates: every edition serves them
|
|
@@ -71,8 +77,6 @@ export const FEATURE_LABELS: Readonly<
|
|
|
71
77
|
> = {
|
|
72
78
|
[Feature.sso_enforcement]: FEATURE_COPY[Feature.sso_enforcement],
|
|
73
79
|
[Feature.byo_provider_keys]: FEATURE_COPY[Feature.byo_provider_keys],
|
|
74
|
-
[Feature.channels]: FEATURE_COPY[Feature.channels],
|
|
75
|
-
[Feature.sharing]: FEATURE_COPY[Feature.sharing],
|
|
76
80
|
};
|
|
77
81
|
|
|
78
82
|
/** Every grantable feature, in contract order (derived from the label map). */
|
|
@@ -163,7 +167,7 @@ export function limitPart(limit: number | undefined, noun: string): string {
|
|
|
163
167
|
return limit === undefined ? `Unlimited ${noun}s` : plural(limit, noun);
|
|
164
168
|
}
|
|
165
169
|
|
|
166
|
-
/** The granted features by name, in contract order: "SSO enforcement,
|
|
170
|
+
/** The granted features by name, in contract order: "SSO enforcement, Bring your own provider keys". */
|
|
167
171
|
export function featureNames(features: readonly number[]): string {
|
|
168
172
|
const names = GRANTABLE_FEATURES.filter((f) => features.includes(f)).map((f) => FEATURE_LABELS[f].label);
|
|
169
173
|
return names.length === 0 ? "No features" : names.join(", ");
|
|
@@ -156,20 +156,18 @@ function ConnectDialogContent({
|
|
|
156
156
|
|
|
157
157
|
const serverName = mcpServer?.metadata?.name ?? slug;
|
|
158
158
|
const serverId = mcpServer?.metadata?.id ?? "";
|
|
159
|
-
const declaredEnvKeys = Object.keys(mcpServer?.spec?.env ?? {});
|
|
160
|
-
|
|
161
159
|
const handleConnect = useCallback(async () => {
|
|
162
160
|
if (!serverId) return;
|
|
163
161
|
|
|
164
162
|
setPhase("connecting");
|
|
165
163
|
try {
|
|
166
|
-
await connect(serverId, activeOrg
|
|
164
|
+
await connect(serverId, activeOrg);
|
|
167
165
|
setPhase("success");
|
|
168
166
|
onConnected?.(serverName);
|
|
169
167
|
} catch {
|
|
170
168
|
setPhase("error");
|
|
171
169
|
}
|
|
172
|
-
}, [serverId, activeOrg,
|
|
170
|
+
}, [serverId, activeOrg, connect, onConnected, serverName]);
|
|
173
171
|
|
|
174
172
|
const handleCredentialSubmit = useCallback(
|
|
175
173
|
async (values: Record<string, EnvVarInput>) => {
|
|
@@ -188,7 +186,7 @@ function ConnectDialogContent({
|
|
|
188
186
|
void handleConnect();
|
|
189
187
|
return;
|
|
190
188
|
}
|
|
191
|
-
oauth.startOAuth(serverId, activeOrg
|
|
189
|
+
oauth.startOAuth(serverId, activeOrg).then(
|
|
192
190
|
() => {
|
|
193
191
|
creds.refetch();
|
|
194
192
|
setPhase("success");
|
|
@@ -203,7 +201,7 @@ function ConnectDialogContent({
|
|
|
203
201
|
setPhase("error");
|
|
204
202
|
},
|
|
205
203
|
);
|
|
206
|
-
}, [serverId, activeOrg,
|
|
204
|
+
}, [serverId, activeOrg, oauth, creds, onConnected, serverName, handleConnect]);
|
|
207
205
|
|
|
208
206
|
// Auto-trigger connect when credentials become ready (manual-only servers)
|
|
209
207
|
useEffect(() => {
|