Skip to content
Draft
12 changes: 12 additions & 0 deletions .changeset/add-agent-action-approval.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
'@clerk/shared': minor
'@clerk/clerk-js': minor
'@clerk/ui': minor
'@clerk/react': minor
'@clerk/react-router': minor
'@clerk/nextjs': minor
'@clerk/tanstack-react-start': minor
'@clerk/localizations': patch
---

Add an experimental `AgentActionApproval` component with an interactive mock approval flow.
6 changes: 6 additions & 0 deletions packages/clerk-js/sandbox/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const AVAILABLE_COMPONENTS = [
'apiKeys',
'configureSSO',
'oauthConsent',
'agentActionApproval',
'taskChooseOrganization',
'taskResetPassword',
'taskSetupMFA',
Expand Down Expand Up @@ -154,6 +155,7 @@ const componentControls: Record<AvailableComponent, ComponentPropsControl> = {
apiKeys: buildComponentControls('apiKeys'),
configureSSO: buildComponentControls('configureSSO'),
oauthConsent: buildComponentControls('oauthConsent'),
agentActionApproval: buildComponentControls('agentActionApproval'),
taskChooseOrganization: buildComponentControls('taskChooseOrganization'),
taskResetPassword: buildComponentControls('taskResetPassword'),
taskSetupMFA: buildComponentControls('taskSetupMFA'),
Expand Down Expand Up @@ -425,6 +427,10 @@ void (async () => {
'/pricing-table': { mount: 'mountPricingTable', component: 'pricingTable' },
'/api-keys': { mount: 'mountAPIKeys', component: 'apiKeys' },
'/configure-sso': { mount: '__internal_mountConfigureSSO', component: 'configureSSO' },
'/agent-action-approval': {
mount: '__experimental_mountAgentActionApproval',
component: 'agentActionApproval',
},
'/task-choose-organization': {
mount: 'mountTaskChooseOrganization',
component: 'taskChooseOrganization',
Expand Down
26 changes: 26 additions & 0 deletions packages/clerk-js/sandbox/scenarios/agent-action-approval.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {
clerkHandlers,
EnvironmentService,
type MockScenario,
SessionService,
setClerkState,
UserService,
} from '@clerk/msw';

export function AgentActionApproval(): MockScenario {
const user = UserService.create();
const session = SessionService.create(user);

setClerkState({
environment: EnvironmentService.MULTI_SESSION,
session,
user,
});

return {
description: 'Interactive agent-action approval prototype',
handlers: clerkHandlers,
initialState: { session, user },
name: 'agent-action-approval',
};
}
1 change: 1 addition & 0 deletions packages/clerk-js/sandbox/scenarios/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export { OrgProfileSeatLimit } from './org-profile-seat-limit';
export { PricingTableSBB } from './pricing-table-sbb';
export { AnnualOnlyPlans } from './annual-only-plans';
export { XProviderEnabled } from './x-provider-enabled';
export { AgentActionApproval } from './agent-action-approval';
5 changes: 5 additions & 0 deletions packages/clerk-js/sandbox/template.html
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,11 @@
label="OAuth Consent"
component="<OAuthConsent />"
></nav-link>
<nav-link
href="/agent-action-approval?scenario=AgentActionApproval"
label="Agent Action Approval"
component="<AgentActionApproval />"
></nav-link>
<nav-link
href="/api-keys"
label="API Keys"
Expand Down
20 changes: 20 additions & 0 deletions packages/clerk-js/src/core/clerk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import type {
__internal_PlanDetailsProps,
__internal_SubscriptionDetailsProps,
__internal_UserVerificationModalProps,
AgentActionApprovalProps,
APIKeysNamespace,
APIKeysProps,
AuthenticateWithBaseParams,
Expand Down Expand Up @@ -1531,6 +1532,25 @@ export class Clerk implements ClerkInterface {
void this.#clerkUI?.then(ui => ui.ensureMounted()).then(controls => controls.unmountComponent({ node }));
};

public __experimental_mountAgentActionApproval = (node: HTMLDivElement, props?: AgentActionApprovalProps) => {
this.assertComponentsReady(this.#clerkUI);
const component = 'AgentActionApproval';
void this.#clerkUI
.then(ui => ui.ensureMounted({ preloadHint: component }))
.then(controls =>
controls.mountComponent({
name: component,
appearanceKey: '__experimental_agentActionApproval',
node,
props,
}),
);
};

public __experimental_unmountAgentActionApproval = (node: HTMLDivElement) => {
void this.#clerkUI?.then(ui => ui.ensureMounted()).then(controls => controls.unmountComponent({ node }));
};

/**
* @deprecated Use mountOAuthConsent instead.
*/
Expand Down
18 changes: 18 additions & 0 deletions packages/localizations/src/ar-SA.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@ import type { LocalizationResource } from '@clerk/shared/types';

export const arSA: LocalizationResource = {
locale: 'ar-SA',
agentActionApproval: {
action__approve: undefined,
action__reject: undefined,
commentLabel: undefined,
commentPlaceholder: undefined,
expiresIn: undefined,
requestedBy: undefined,
subtitle: undefined,
terminal: {
approvedSubtitle: undefined,
approvedTitle: undefined,
expiredSubtitle: undefined,
expiredTitle: undefined,
rejectedSubtitle: undefined,
rejectedTitle: undefined,
},
title: undefined,
},
apiKeys: {
action__add: undefined,
action__search: undefined,
Expand Down
18 changes: 18 additions & 0 deletions packages/localizations/src/be-BY.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@ import type { LocalizationResource } from '@clerk/shared/types';

export const beBY: LocalizationResource = {
locale: 'be-BY',
agentActionApproval: {
action__approve: undefined,
action__reject: undefined,
commentLabel: undefined,
commentPlaceholder: undefined,
expiresIn: undefined,
requestedBy: undefined,
subtitle: undefined,
terminal: {
approvedSubtitle: undefined,
approvedTitle: undefined,
expiredSubtitle: undefined,
expiredTitle: undefined,
rejectedSubtitle: undefined,
rejectedTitle: undefined,
},
title: undefined,
},
apiKeys: {
action__add: undefined,
action__search: undefined,
Expand Down
18 changes: 18 additions & 0 deletions packages/localizations/src/bg-BG.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@ import type { LocalizationResource } from '@clerk/shared/types';

export const bgBG: LocalizationResource = {
locale: 'bg-BG',
agentActionApproval: {
action__approve: undefined,
action__reject: undefined,
commentLabel: undefined,
commentPlaceholder: undefined,
expiresIn: undefined,
requestedBy: undefined,
subtitle: undefined,
terminal: {
approvedSubtitle: undefined,
approvedTitle: undefined,
expiredSubtitle: undefined,
expiredTitle: undefined,
rejectedSubtitle: undefined,
rejectedTitle: undefined,
},
title: undefined,
},
apiKeys: {
action__add: undefined,
action__search: undefined,
Expand Down
18 changes: 18 additions & 0 deletions packages/localizations/src/bn-IN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@ import type { LocalizationResource } from '@clerk/shared/types';

export const bnIN: LocalizationResource = {
locale: 'bn-IN',
agentActionApproval: {
action__approve: undefined,
action__reject: undefined,
commentLabel: undefined,
commentPlaceholder: undefined,
expiresIn: undefined,
requestedBy: undefined,
subtitle: undefined,
terminal: {
approvedSubtitle: undefined,
approvedTitle: undefined,
expiredSubtitle: undefined,
expiredTitle: undefined,
rejectedSubtitle: undefined,
rejectedTitle: undefined,
},
title: undefined,
},
apiKeys: {
action__add: 'নতুন কী যোগ করুন',
action__search: 'কী অনুসন্ধান করুন',
Expand Down
18 changes: 18 additions & 0 deletions packages/localizations/src/ca-ES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@ import type { LocalizationResource } from '@clerk/shared/types';

export const caES: LocalizationResource = {
locale: 'ca-ES',
agentActionApproval: {
action__approve: undefined,
action__reject: undefined,
commentLabel: undefined,
commentPlaceholder: undefined,
expiresIn: undefined,
requestedBy: undefined,
subtitle: undefined,
terminal: {
approvedSubtitle: undefined,
approvedTitle: undefined,
expiredSubtitle: undefined,
expiredTitle: undefined,
rejectedSubtitle: undefined,
rejectedTitle: undefined,
},
title: undefined,
},
apiKeys: {
action__add: undefined,
action__search: undefined,
Expand Down
18 changes: 18 additions & 0 deletions packages/localizations/src/cs-CZ.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@ import type { LocalizationResource } from '@clerk/shared/types';

export const csCZ: LocalizationResource = {
locale: 'cs-CZ',
agentActionApproval: {
action__approve: undefined,
action__reject: undefined,
commentLabel: undefined,
commentPlaceholder: undefined,
expiresIn: undefined,
requestedBy: undefined,
subtitle: undefined,
terminal: {
approvedSubtitle: undefined,
approvedTitle: undefined,
expiredSubtitle: undefined,
expiredTitle: undefined,
rejectedSubtitle: undefined,
rejectedTitle: undefined,
},
title: undefined,
},
apiKeys: {
action__add: 'Přidat nový klíč',
action__search: 'Vyhledat klíče',
Expand Down
18 changes: 18 additions & 0 deletions packages/localizations/src/da-DK.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@ import type { LocalizationResource } from '@clerk/shared/types';

export const daDK: LocalizationResource = {
locale: 'da-DK',
agentActionApproval: {
action__approve: undefined,
action__reject: undefined,
commentLabel: undefined,
commentPlaceholder: undefined,
expiresIn: undefined,
requestedBy: undefined,
subtitle: undefined,
terminal: {
approvedSubtitle: undefined,
approvedTitle: undefined,
expiredSubtitle: undefined,
expiredTitle: undefined,
rejectedSubtitle: undefined,
rejectedTitle: undefined,
},
title: undefined,
},
apiKeys: {
action__add: undefined,
action__search: undefined,
Expand Down
18 changes: 18 additions & 0 deletions packages/localizations/src/de-DE.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@ import type { LocalizationResource } from '@clerk/shared/types';

export const deDE: LocalizationResource = {
locale: 'de-DE',
agentActionApproval: {
action__approve: undefined,
action__reject: undefined,
commentLabel: undefined,
commentPlaceholder: undefined,
expiresIn: undefined,
requestedBy: undefined,
subtitle: undefined,
terminal: {
approvedSubtitle: undefined,
approvedTitle: undefined,
expiredSubtitle: undefined,
expiredTitle: undefined,
rejectedSubtitle: undefined,
rejectedTitle: undefined,
},
title: undefined,
},
apiKeys: {
action__add: 'Neuen API-Key hinzufügen',
action__search: 'Suche',
Expand Down
18 changes: 18 additions & 0 deletions packages/localizations/src/el-GR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@ import type { LocalizationResource } from '@clerk/shared/types';

export const elGR: LocalizationResource = {
locale: 'el-GR',
agentActionApproval: {
action__approve: undefined,
action__reject: undefined,
commentLabel: undefined,
commentPlaceholder: undefined,
expiresIn: undefined,
requestedBy: undefined,
subtitle: undefined,
terminal: {
approvedSubtitle: undefined,
approvedTitle: undefined,
expiredSubtitle: undefined,
expiredTitle: undefined,
rejectedSubtitle: undefined,
rejectedTitle: undefined,
},
title: undefined,
},
apiKeys: {
action__add: 'Προσθήκη',
action__search: 'Αναζήτηση',
Expand Down
18 changes: 18 additions & 0 deletions packages/localizations/src/en-GB.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@ import type { LocalizationResource } from '@clerk/shared/types';

export const enGB: LocalizationResource = {
locale: 'en-GB',
agentActionApproval: {
action__approve: undefined,
action__reject: undefined,
commentLabel: undefined,
commentPlaceholder: undefined,
expiresIn: undefined,
requestedBy: undefined,
subtitle: undefined,
terminal: {
approvedSubtitle: undefined,
approvedTitle: undefined,
expiredSubtitle: undefined,
expiredTitle: undefined,
rejectedSubtitle: undefined,
rejectedTitle: undefined,
},
title: undefined,
},
apiKeys: {
action__add: undefined,
action__search: undefined,
Expand Down
19 changes: 19 additions & 0 deletions packages/localizations/src/en-US.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,25 @@ import type { LocalizationResource } from '@clerk/shared/types';

export const enUS: LocalizationResource = {
locale: 'en-US',
agentActionApproval: {
action__approve: 'Approve',
action__reject: 'Reject',
commentLabel: 'Comment (optional)',
commentPlaceholder: 'Add context for the requesting application',
expiresIn: 'Approval window closes in {{remaining}}',
requestedBy: 'Requested by {{agent}} · {{createdAt}}',
subtitle: 'Review the details before allowing this action to continue.',
terminal: {
approvedSubtitle: 'You can close this window, return to your agent, and retry the request.',
approvedTitle: 'Agent is now authorized to continue',
expiredSubtitle:
'The approval window closed. No action was taken. You can close this window and return to your agent.',
expiredTitle: 'Approval window closed',
rejectedSubtitle: 'No action was taken. You can close this window and return to your agent.',
rejectedTitle: 'Action rejected',
},
title: 'Approve agent action',
},
apiKeys: {
action__add: 'Add new key',
action__search: 'Search keys',
Expand Down
Loading
Loading