@stigmer/react 3.40.0 → 3.40.1

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.
@@ -41,6 +41,11 @@ export interface ChannelAppDetailPanelProps {
41
41
  * untouched preserves the stored values (rotate one secret without
42
42
  * re-entering the others). Deletion is refused server-side while any
43
43
  * agent channel still installs through this app.
44
+ *
45
+ * The credentials form is offered to a caller who may edit the app
46
+ * (`can_edit`) and the deletion section to one who may delete it
47
+ * (`can_delete`): its creator and the organization's admins. Someone
48
+ * granted viewer on an app sees its setup values with no actions.
44
49
  */
45
50
  export declare function ChannelAppDetailPanel({ channelApp, consoleOrigin, createHandoff, onUpdated, onDeleted, onBack, className, }: ChannelAppDetailPanelProps): import("react/jsx-runtime").JSX.Element;
46
51
  //# sourceMappingURL=ChannelAppDetailPanel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChannelAppDetailPanel.d.ts","sourceRoot":"","sources":["../src/channel-app/ChannelAppDetailPanel.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yDAAyD,CAAC;AAI1F,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAiBzE,+CAA+C;AAC/C,MAAM,WAAW,0BAA0B;IACzC,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;;;;;;;OAOG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,uBAAuB,CAAC;IACjD,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,CAAC;IAC/C,sCAAsC;IACtC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,sDAAsD;IACtD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,yDAAyD;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,UAAU,EACV,aAAa,EACb,aAAa,EACb,SAAS,EACT,SAAS,EACT,MAAM,EACN,SAAS,GACV,EAAE,0BAA0B,2CAkG5B"}
1
+ {"version":3,"file":"ChannelAppDetailPanel.d.ts","sourceRoot":"","sources":["../src/channel-app/ChannelAppDetailPanel.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yDAAyD,CAAC;AAI1F,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAkBzE,+CAA+C;AAC/C,MAAM,WAAW,0BAA0B;IACzC,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;;;;;;;OAOG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,uBAAuB,CAAC;IACjD,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,CAAC;IAC/C,sCAAsC;IACtC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,sDAAsD;IACtD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,yDAAyD;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,UAAU,EACV,aAAa,EACb,aAAa,EACb,SAAS,EACT,SAAS,EACT,MAAM,EACN,SAAS,GACV,EAAE,0BAA0B,2CAuG5B"}
@@ -9,6 +9,7 @@ import { useDeleteChannelApp } from "./useDeleteChannelApp.js";
9
9
  import { buildSlackChannelAppManifest, slackChannelAppRedirectUrl, slackChannelAppWebhookUrl, } from "./slackAppSetup.js";
10
10
  import { WHATSAPP_CHANNEL_APP_WEBHOOK_FIELDS, whatsappChannelAppWebhookUrl, } from "./whatsappAppSetup.js";
11
11
  import { CopyBlock, CopyRow, FormField } from "./internal.js";
12
+ import { PermissionGate } from "../iam-policy/PermissionGate.js";
12
13
  import { SpinnerIcon } from "../internal/SpinnerIcon.js";
13
14
  /**
14
15
  * Detail view for one {@link ChannelApp}: the "finish setup at the
@@ -24,6 +25,11 @@ import { SpinnerIcon } from "../internal/SpinnerIcon.js";
24
25
  * untouched preserves the stored values (rotate one secret without
25
26
  * re-entering the others). Deletion is refused server-side while any
26
27
  * agent channel still installs through this app.
28
+ *
29
+ * The credentials form is offered to a caller who may edit the app
30
+ * (`can_edit`) and the deletion section to one who may delete it
31
+ * (`can_delete`): its creator and the organization's admins. Someone
32
+ * granted viewer on an app sees its setup values with no actions.
27
33
  */
28
34
  export function ChannelAppDetailPanel({ channelApp, consoleOrigin, createHandoff, onUpdated, onDeleted, onBack, className, }) {
29
35
  const { deleteApp, isDeleting, error: deleteError } = useDeleteChannelApp();
@@ -43,7 +49,7 @@ export function ChannelAppDetailPanel({ channelApp, consoleOrigin, createHandoff
43
49
  setConfirmingDelete(false);
44
50
  }
45
51
  }, [deleteApp, appId, onDeleted]);
46
- return (_jsxs("div", { className: cn("stg:space-y-5", className), children: [_jsxs("div", { className: "stg:flex stg:items-center stg:justify-between", children: [_jsxs("div", { className: "stg:min-w-0", children: [_jsx("h3", { className: "stg:truncate stg:text-sm stg:font-semibold stg:text-foreground", children: name }), _jsx("p", { className: "stg:font-mono stg:text-[0.65rem] stg:text-muted-foreground", children: appId })] }), onBack && (_jsx("button", { type: "button", onClick: onBack, className: "stg:text-muted-foreground stg:hover:text-foreground stg:shrink-0 stg:text-xs stg:transition-colors", children: "\u2190 Back" }))] }), providerCase === "slack" ? (_jsx(SlackAppDetail, { channelApp: channelApp, consoleOrigin: consoleOrigin, onUpdated: onUpdated })) : providerCase === "whatsapp" ? (_jsx(WhatsAppAppDetail, { channelApp: channelApp, createHandoff: createHandoff, onUpdated: onUpdated })) : null, _jsxs("section", { className: "stg:border-t stg:border-border stg:pt-3", "aria-label": "Danger zone", children: [deleteError && (_jsx("p", { className: "stg:text-destructive stg:mb-2 stg:text-[0.65rem]", role: "alert", children: getUserMessage(deleteError) })), confirmingDelete ? (_jsxs("div", { className: "stg:flex stg:items-center stg:gap-2", children: [_jsx("p", { className: "stg:text-xs stg:text-foreground", children: "Delete this channel app? Channels installing through it must be disconnected first." }), _jsxs("button", { type: "button", onClick: handleDelete, disabled: isDeleting, className: cn("stg:inline-flex stg:items-center stg:gap-1.5 stg:rounded-md stg:px-2.5 stg:py-1 stg:text-xs stg:font-medium", "stg:bg-destructive stg:text-destructive-foreground stg:hover:opacity-90", "stg:disabled:pointer-events-none stg:disabled:opacity-40"), children: [isDeleting && _jsx(SpinnerIcon, { size: 12 }), "Delete"] }), _jsx("button", { type: "button", onClick: () => setConfirmingDelete(false), disabled: isDeleting, className: "stg:text-muted-foreground stg:hover:text-foreground stg:text-xs stg:transition-colors", children: "Keep" })] })) : (_jsx("button", { type: "button", onClick: () => setConfirmingDelete(true), className: "stg:text-destructive stg:text-xs stg:font-medium stg:hover:opacity-80", children: "Delete channel app" }))] })] }));
52
+ return (_jsxs("div", { className: cn("stg:space-y-5", className), children: [_jsxs("div", { className: "stg:flex stg:items-center stg:justify-between", children: [_jsxs("div", { className: "stg:min-w-0", children: [_jsx("h3", { className: "stg:truncate stg:text-sm stg:font-semibold stg:text-foreground", children: name }), _jsx("p", { className: "stg:font-mono stg:text-[0.65rem] stg:text-muted-foreground", children: appId })] }), onBack && (_jsx("button", { type: "button", onClick: onBack, className: "stg:text-muted-foreground stg:hover:text-foreground stg:shrink-0 stg:text-xs stg:transition-colors", children: "\u2190 Back" }))] }), providerCase === "slack" ? (_jsx(SlackAppDetail, { channelApp: channelApp, consoleOrigin: consoleOrigin, onUpdated: onUpdated })) : providerCase === "whatsapp" ? (_jsx(WhatsAppAppDetail, { channelApp: channelApp, createHandoff: createHandoff, onUpdated: onUpdated })) : null, _jsx(PermissionGate, { resource: { kind: "channel_app", id: appId }, relation: "can_delete", children: _jsxs("section", { className: "stg:border-t stg:border-border stg:pt-3", "aria-label": "Danger zone", children: [deleteError && (_jsx("p", { className: "stg:text-destructive stg:mb-2 stg:text-[0.65rem]", role: "alert", children: getUserMessage(deleteError) })), confirmingDelete ? (_jsxs("div", { className: "stg:flex stg:items-center stg:gap-2", children: [_jsx("p", { className: "stg:text-xs stg:text-foreground", children: "Delete this channel app? Channels installing through it must be disconnected first." }), _jsxs("button", { type: "button", onClick: handleDelete, disabled: isDeleting, className: cn("stg:inline-flex stg:items-center stg:gap-1.5 stg:rounded-md stg:px-2.5 stg:py-1 stg:text-xs stg:font-medium", "stg:bg-destructive stg:text-destructive-foreground stg:hover:opacity-90", "stg:disabled:pointer-events-none stg:disabled:opacity-40"), children: [isDeleting && _jsx(SpinnerIcon, { size: 12 }), "Delete"] }), _jsx("button", { type: "button", onClick: () => setConfirmingDelete(false), disabled: isDeleting, className: "stg:text-muted-foreground stg:hover:text-foreground stg:text-xs stg:transition-colors", children: "Keep" })] })) : (_jsx("button", { type: "button", onClick: () => setConfirmingDelete(true), className: "stg:text-destructive stg:text-xs stg:font-medium stg:hover:opacity-80", children: "Delete channel app" }))] }) })] }));
47
53
  }
48
54
  // ---------------------------------------------------------------------------
49
55
  // Slack — finish setup in Slack + credential rotation
@@ -91,7 +97,7 @@ function SlackAppDetail({ channelApp, consoleOrigin, onUpdated, }) {
91
97
  // error state is managed by useUpdateChannelApp
92
98
  }
93
99
  }, [canSave, clearError, update, channelApp, clientId, clientSecret, signingSecret, onUpdated]);
94
- return (_jsxs(_Fragment, { children: [_jsxs("section", { className: "stg:space-y-2", "aria-label": "Finish setup in Slack", children: [_jsx("p", { className: "stg:text-xs stg:font-medium stg:text-foreground", children: "Finish setup in Slack" }), _jsxs("p", { className: "stg:text-[0.65rem] stg:text-muted-foreground", children: ["On the app's ", _jsx("span", { className: "stg:font-medium", children: "Event Subscriptions" }), " page, enable events and set the request URL below (Slack verifies it immediately). The completed manifest is also available for review or re-paste."] }), _jsx(CopyRow, { label: "Events request URL", value: webhookUrl, copyTargetId: "stgm-chapp-webhook-copy" }), _jsx(CopyRow, { label: "OAuth redirect URL", value: redirectUrl }), _jsx(CopyBlock, { label: "Completed app manifest", value: manifest })] }), _jsxs("form", { onSubmit: handleSave, className: "stg:space-y-3", "aria-label": "Credentials", children: [_jsx("p", { className: "stg:text-xs stg:font-medium stg:text-foreground", children: "Credentials" }), _jsxs("p", { className: "stg:-mt-2 stg:text-[0.65rem] stg:text-muted-foreground", children: ["Secrets show as ", _jsx("code", { className: "stg:font-mono", children: "***REDACTED***" }), "; leave a field untouched to keep its stored value, or paste a new one to rotate it."] }), _jsx(FormField, { id: `${baseId}-client-id`, label: "Client ID", value: clientId, onChange: setClientId, placeholder: "1234567890.0987654321", disabled: isUpdating, required: true }), _jsx(FormField, { id: `${baseId}-client-secret`, label: "Client secret", value: clientSecret, onChange: setClientSecret, placeholder: "Client secret", type: "password", disabled: isUpdating, required: true }), _jsx(FormField, { id: `${baseId}-signing-secret`, label: "Signing secret", value: signingSecret, onChange: setSigningSecret, placeholder: "Signing secret", type: "password", disabled: isUpdating, required: true }), updateError && (_jsx("p", { className: "stg:text-destructive stg:text-[0.65rem]", role: "alert", children: getUserMessage(updateError) })), _jsxs("button", { type: "submit", disabled: !canSave, className: cn("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", "stg:bg-primary stg:text-primary-foreground stg:hover:bg-primary-hover", "stg:disabled:pointer-events-none stg:disabled:opacity-40"), children: [isUpdating && _jsx(SpinnerIcon, { size: 12 }), "Save credentials"] })] })] }));
100
+ return (_jsxs(_Fragment, { children: [_jsxs("section", { className: "stg:space-y-2", "aria-label": "Finish setup in Slack", children: [_jsx("p", { className: "stg:text-xs stg:font-medium stg:text-foreground", children: "Finish setup in Slack" }), _jsxs("p", { className: "stg:text-[0.65rem] stg:text-muted-foreground", children: ["On the app's ", _jsx("span", { className: "stg:font-medium", children: "Event Subscriptions" }), " page, enable events and set the request URL below (Slack verifies it immediately). The completed manifest is also available for review or re-paste."] }), _jsx(CopyRow, { label: "Events request URL", value: webhookUrl, copyTargetId: "stgm-chapp-webhook-copy" }), _jsx(CopyRow, { label: "OAuth redirect URL", value: redirectUrl }), _jsx(CopyBlock, { label: "Completed app manifest", value: manifest })] }), _jsx(PermissionGate, { resource: { kind: "channel_app", id: appId }, relation: "can_edit", children: _jsxs("form", { onSubmit: handleSave, className: "stg:space-y-3", "aria-label": "Credentials", children: [_jsx("p", { className: "stg:text-xs stg:font-medium stg:text-foreground", children: "Credentials" }), _jsxs("p", { className: "stg:-mt-2 stg:text-[0.65rem] stg:text-muted-foreground", children: ["Secrets show as ", _jsx("code", { className: "stg:font-mono", children: "***REDACTED***" }), "; leave a field untouched to keep its stored value, or paste a new one to rotate it."] }), _jsx(FormField, { id: `${baseId}-client-id`, label: "Client ID", value: clientId, onChange: setClientId, placeholder: "1234567890.0987654321", disabled: isUpdating, required: true }), _jsx(FormField, { id: `${baseId}-client-secret`, label: "Client secret", value: clientSecret, onChange: setClientSecret, placeholder: "Client secret", type: "password", disabled: isUpdating, required: true }), _jsx(FormField, { id: `${baseId}-signing-secret`, label: "Signing secret", value: signingSecret, onChange: setSigningSecret, placeholder: "Signing secret", type: "password", disabled: isUpdating, required: true }), updateError && (_jsx("p", { className: "stg:text-destructive stg:text-[0.65rem]", role: "alert", children: getUserMessage(updateError) })), _jsxs("button", { type: "submit", disabled: !canSave, className: cn("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", "stg:bg-primary stg:text-primary-foreground stg:hover:bg-primary-hover", "stg:disabled:pointer-events-none stg:disabled:opacity-40"), children: [isUpdating && _jsx(SpinnerIcon, { size: 12 }), "Save credentials"] })] }) })] }));
95
101
  }
96
102
  // ---------------------------------------------------------------------------
97
103
  // WhatsApp — finish setup in Meta + credential rotation
@@ -140,6 +146,6 @@ function WhatsAppAppDetail({ channelApp, createHandoff, onUpdated, }) {
140
146
  // error state is managed by useUpdateChannelApp
141
147
  }
142
148
  }, [canSave, clearError, update, channelApp, metaAppId, appSecret, accessToken, verifyToken, onUpdated]);
143
- return (_jsxs(_Fragment, { children: [_jsxs("section", { className: "stg:space-y-2", "aria-label": "Finish setup in Meta", children: [_jsx("p", { className: "stg:text-xs stg:font-medium stg:text-foreground", children: "Finish setup in Meta" }), _jsxs("p", { className: "stg:text-[0.65rem] stg:text-muted-foreground", children: ["On the app's ", _jsx("span", { className: "stg:font-medium", children: "WhatsApp \u2192 Configuration" }), " page, set the callback URL and verify token below, click ", _jsx("span", { className: "stg:font-medium", children: "Verify and save" }), " ", "(Meta verifies immediately), then subscribe to the", " ", _jsx("span", { className: "stg:font-medium", children: WHATSAPP_CHANNEL_APP_WEBHOOK_FIELDS.join(", ") }), " ", "webhook field."] }), _jsx(CopyRow, { label: "Callback URL", value: webhookUrl, copyTargetId: "stgm-chapp-webhook-copy" }), createHandoff?.verifyToken ? (_jsx(CopyRow, { label: "Verify token", value: createHandoff.verifyToken, copyTargetId: "stgm-chapp-verify-token-copy" })) : (_jsxs("div", { className: "stg:space-y-1", children: [_jsx("p", { className: "stg:text-xs stg:font-medium stg:text-foreground", children: "Verify token" }), _jsx("p", { className: "stg:text-[0.65rem] stg:text-muted-foreground", children: "Shown once at registration. If you no longer have it, paste a new one below and update Meta's webhook configuration to match." })] }))] }), _jsxs("form", { onSubmit: handleSave, className: "stg:space-y-3", "aria-label": "Credentials", children: [_jsx("p", { className: "stg:text-xs stg:font-medium stg:text-foreground", children: "Credentials" }), _jsxs("p", { className: "stg:-mt-2 stg:text-[0.65rem] stg:text-muted-foreground", children: ["Secrets show as ", _jsx("code", { className: "stg:font-mono", children: "***REDACTED***" }), "; leave a field untouched to keep its stored value, or paste a new one to rotate it."] }), _jsx(FormField, { id: `${baseId}-app-id`, label: "App ID", value: metaAppId, onChange: setMetaAppId, placeholder: "1234567890123456", disabled: isUpdating, required: true }), _jsx(FormField, { id: `${baseId}-app-secret`, label: "App secret", value: appSecret, onChange: setAppSecret, placeholder: "App secret", type: "password", disabled: isUpdating, required: true }), _jsx(FormField, { id: `${baseId}-access-token`, label: "Access token", value: accessToken, onChange: setAccessToken, placeholder: "Long-lived system-user access token", type: "password", disabled: isUpdating, required: true }), _jsx(FormField, { id: `${baseId}-verify-token`, label: "Verify token", value: verifyToken, onChange: setVerifyToken, placeholder: "Verify token", type: "password", hint: "Rotating it? Update Meta's webhook configuration to the same value.", disabled: isUpdating, required: true }), updateError && (_jsx("p", { className: "stg:text-destructive stg:text-[0.65rem]", role: "alert", children: getUserMessage(updateError) })), _jsxs("button", { type: "submit", disabled: !canSave, className: cn("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", "stg:bg-primary stg:text-primary-foreground stg:hover:bg-primary-hover", "stg:disabled:pointer-events-none stg:disabled:opacity-40"), children: [isUpdating && _jsx(SpinnerIcon, { size: 12 }), "Save credentials"] })] })] }));
149
+ return (_jsxs(_Fragment, { children: [_jsxs("section", { className: "stg:space-y-2", "aria-label": "Finish setup in Meta", children: [_jsx("p", { className: "stg:text-xs stg:font-medium stg:text-foreground", children: "Finish setup in Meta" }), _jsxs("p", { className: "stg:text-[0.65rem] stg:text-muted-foreground", children: ["On the app's ", _jsx("span", { className: "stg:font-medium", children: "WhatsApp \u2192 Configuration" }), " page, set the callback URL and verify token below, click ", _jsx("span", { className: "stg:font-medium", children: "Verify and save" }), " ", "(Meta verifies immediately), then subscribe to the", " ", _jsx("span", { className: "stg:font-medium", children: WHATSAPP_CHANNEL_APP_WEBHOOK_FIELDS.join(", ") }), " ", "webhook field."] }), _jsx(CopyRow, { label: "Callback URL", value: webhookUrl, copyTargetId: "stgm-chapp-webhook-copy" }), createHandoff?.verifyToken ? (_jsx(CopyRow, { label: "Verify token", value: createHandoff.verifyToken, copyTargetId: "stgm-chapp-verify-token-copy" })) : (_jsxs("div", { className: "stg:space-y-1", children: [_jsx("p", { className: "stg:text-xs stg:font-medium stg:text-foreground", children: "Verify token" }), _jsx("p", { className: "stg:text-[0.65rem] stg:text-muted-foreground", children: "Shown once at registration. If you no longer have it, paste a new one below and update Meta's webhook configuration to match." })] }))] }), _jsx(PermissionGate, { resource: { kind: "channel_app", id: appId }, relation: "can_edit", children: _jsxs("form", { onSubmit: handleSave, className: "stg:space-y-3", "aria-label": "Credentials", children: [_jsx("p", { className: "stg:text-xs stg:font-medium stg:text-foreground", children: "Credentials" }), _jsxs("p", { className: "stg:-mt-2 stg:text-[0.65rem] stg:text-muted-foreground", children: ["Secrets show as ", _jsx("code", { className: "stg:font-mono", children: "***REDACTED***" }), "; leave a field untouched to keep its stored value, or paste a new one to rotate it."] }), _jsx(FormField, { id: `${baseId}-app-id`, label: "App ID", value: metaAppId, onChange: setMetaAppId, placeholder: "1234567890123456", disabled: isUpdating, required: true }), _jsx(FormField, { id: `${baseId}-app-secret`, label: "App secret", value: appSecret, onChange: setAppSecret, placeholder: "App secret", type: "password", disabled: isUpdating, required: true }), _jsx(FormField, { id: `${baseId}-access-token`, label: "Access token", value: accessToken, onChange: setAccessToken, placeholder: "Long-lived system-user access token", type: "password", disabled: isUpdating, required: true }), _jsx(FormField, { id: `${baseId}-verify-token`, label: "Verify token", value: verifyToken, onChange: setVerifyToken, placeholder: "Verify token", type: "password", hint: "Rotating it? Update Meta's webhook configuration to the same value.", disabled: isUpdating, required: true }), updateError && (_jsx("p", { className: "stg:text-destructive stg:text-[0.65rem]", role: "alert", children: getUserMessage(updateError) })), _jsxs("button", { type: "submit", disabled: !canSave, className: cn("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", "stg:bg-primary stg:text-primary-foreground stg:hover:bg-primary-hover", "stg:disabled:pointer-events-none stg:disabled:opacity-40"), children: [isUpdating && _jsx(SpinnerIcon, { size: 12 }), "Save credentials"] })] }) })] }));
144
150
  }
145
151
  //# sourceMappingURL=ChannelAppDetailPanel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChannelAppDetailPanel.js","sourceRoot":"","sources":["../src/channel-app/ChannelAppDetailPanel.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ChannelAppDetailPanel.js","sourceRoot":"","sources":["../src/channel-app/ChannelAppDetailPanel.tsx"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { ReactNode } from "react";
1
2
  import type { ChannelApp } from "@stigmer/protos/ai/stigmer/agentic/channelapp/v1/api_pb";
2
3
  /** Props for {@link ChannelAppListPanel}. */
3
4
  export interface ChannelAppListPanelProps {
@@ -10,13 +11,21 @@ export interface ChannelAppListPanelProps {
10
11
  readonly onEdit?: (app: ChannelApp) => void;
11
12
  /** Re-expose refetch so parents can trigger a list refresh. */
12
13
  readonly onRefetchRef?: (refetch: () => void) => void;
14
+ /**
15
+ * Shown when the list is empty. Defaults to "No channel apps registered
16
+ * yet." The list holds only the apps the caller may view (their creator,
17
+ * anyone granted viewer on one, and the organization's admins), so a host
18
+ * that knows the caller may not manage channel apps should say who does
19
+ * instead.
20
+ */
21
+ readonly emptyState?: ReactNode;
13
22
  /** Additional CSS class names for the root container. */
14
23
  readonly className?: string;
15
24
  }
16
25
  /**
17
- * Displays the {@link ChannelApp} resources owned by an organization —
18
- * the customer's own provider apps (Slack, Meta/WhatsApp) that agent
19
- * channels can install through.
26
+ * Displays the {@link ChannelApp} resources of an organization that the
27
+ * caller may view — the customer's own provider apps (Slack,
28
+ * Meta/WhatsApp) that agent channels can install through.
20
29
  *
21
30
  * Each row shows the app name, provider, the provider's non-secret app
22
31
  * identifier, and creation date. Secret fields never appear (they
@@ -32,5 +41,5 @@ export interface ChannelAppListPanelProps {
32
41
  * />
33
42
  * ```
34
43
  */
35
- export declare function ChannelAppListPanel({ org, onEdit, onRefetchRef, className, }: ChannelAppListPanelProps): import("react/jsx-runtime").JSX.Element;
44
+ export declare function ChannelAppListPanel({ org, onEdit, onRefetchRef, emptyState, className, }: ChannelAppListPanelProps): import("react/jsx-runtime").JSX.Element;
36
45
  //# sourceMappingURL=ChannelAppListPanel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChannelAppListPanel.d.ts","sourceRoot":"","sources":["../src/channel-app/ChannelAppListPanel.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yDAAyD,CAAC;AAQ1F,6CAA6C;AAC7C,MAAM,WAAW,wBAAwB;IACvC,kDAAkD;IAClD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,CAAC;IAC5C,+DAA+D;IAC/D,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACtD,yDAAyD;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,GAAG,EACH,MAAM,EACN,YAAY,EACZ,SAAS,GACV,EAAE,wBAAwB,2CAyD1B"}
1
+ {"version":3,"file":"ChannelAppListPanel.d.ts","sourceRoot":"","sources":["../src/channel-app/ChannelAppListPanel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yDAAyD,CAAC;AAQ1F,6CAA6C;AAC7C,MAAM,WAAW,wBAAwB;IACvC,kDAAkD;IAClD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,CAAC;IAC5C,+DAA+D;IAC/D,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACtD;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC;IAChC,yDAAyD;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,GAAG,EACH,MAAM,EACN,YAAY,EACZ,UAA8C,EAC9C,SAAS,GACV,EAAE,wBAAwB,2CAyD1B"}
@@ -6,9 +6,9 @@ import { timestampDate } from "@bufbuild/protobuf/wkt";
6
6
  import { channelProviderOf } from "../channel/providers.js";
7
7
  import { useChannelAppList } from "./useChannelAppList.js";
8
8
  /**
9
- * Displays the {@link ChannelApp} resources owned by an organization —
10
- * the customer's own provider apps (Slack, Meta/WhatsApp) that agent
11
- * channels can install through.
9
+ * Displays the {@link ChannelApp} resources of an organization that the
10
+ * caller may view — the customer's own provider apps (Slack,
11
+ * Meta/WhatsApp) that agent channels can install through.
12
12
  *
13
13
  * Each row shows the app name, provider, the provider's non-secret app
14
14
  * identifier, and creation date. Secret fields never appear (they
@@ -24,7 +24,7 @@ import { useChannelAppList } from "./useChannelAppList.js";
24
24
  * />
25
25
  * ```
26
26
  */
27
- export function ChannelAppListPanel({ org, onEdit, onRefetchRef, className, }) {
27
+ export function ChannelAppListPanel({ org, onEdit, onRefetchRef, emptyState = "No channel apps registered yet.", className, }) {
28
28
  const { channelApps, isLoading, error, refetch } = useChannelAppList(org);
29
29
  if (onRefetchRef) {
30
30
  onRefetchRef(refetch);
@@ -36,7 +36,7 @@ export function ChannelAppListPanel({ org, onEdit, onRefetchRef, className, }) {
36
36
  return (_jsx("p", { className: cn("stg:text-destructive stg:text-xs", className), role: "alert", children: getUserMessage(error) }));
37
37
  }
38
38
  if (channelApps.length === 0) {
39
- return (_jsx("p", { className: cn("stg:text-muted-foreground stg:py-4 stg:text-center stg:text-xs", className), children: "No channel apps registered yet." }));
39
+ return (_jsx("p", { className: cn("stg:text-muted-foreground stg:py-4 stg:text-center stg:text-xs", className), children: emptyState }));
40
40
  }
41
41
  return (_jsx("div", { className: cn("stg:space-y-2", className), role: "list", "aria-label": "Channel apps", children: channelApps.map((app) => (_jsx(ChannelAppRow, { channelApp: app, onEdit: onEdit ? () => onEdit(app) : undefined }, app.metadata?.id ?? ""))) }));
42
42
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ChannelAppListPanel.js","sourceRoot":"","sources":["../src/channel-app/ChannelAppListPanel.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ChannelAppListPanel.js","sourceRoot":"","sources":["../src/channel-app/ChannelAppListPanel.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AA6B3D;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAClC,GAAG,EACH,MAAM,EACN,YAAY,EACZ,UAAU,GAAG,iCAAiC,EAC9C,SAAS,GACgB;IACzB,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAE1E,IAAI,YAAY,EAAE,CAAC;QACjB,YAAY,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,CACL,cACE,SAAS,EAAE,EAAE,CAAC,eAAe,EAAE,SAAS,CAAC,eAC/B,MAAM,gBACL,sBAAsB,YAEhC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CACnC,cAAa,SAAS,EAAC,+DAA+D,IAA5E,CAAC,CAA8E,CAC1F,CAAC,GACE,CACP,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CACL,YAAG,SAAS,EAAE,EAAE,CAAC,kCAAkC,EAAE,SAAS,CAAC,EAAE,IAAI,EAAC,OAAO,YAC1E,cAAc,CAAC,KAAK,CAAC,GACpB,CACL,CAAC;IACJ,CAAC;IAED,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,CACL,YACE,SAAS,EAAE,EAAE,CACX,gEAAgE,EAChE,SAAS,CACV,YAEA,UAAU,GACT,CACL,CAAC;IACJ,CAAC;IAED,OAAO,CACL,cACE,SAAS,EAAE,EAAE,CAAC,eAAe,EAAE,SAAS,CAAC,EACzC,IAAI,EAAC,MAAM,gBACA,cAAc,YAExB,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACxB,KAAC,aAAa,IAEZ,UAAU,EAAE,GAAG,EACf,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,IAFzC,GAAG,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAG3B,CACH,CAAC,GACE,CACP,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E,SAAS,aAAa,CAAC,EACrB,UAAU,EACV,MAAM,GAIP;IACC,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC;IAC7C,MAAM,YAAY,GAAG,UAAU,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC;IAC3D,MAAM,QAAQ,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAC;IACjD,qEAAqE;IACrE,kDAAkD;IAClD,MAAM,aAAa,GACjB,UAAU,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,KAAK,OAAO;QAC/C,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ;QAC/C,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,KAAK,UAAU;YACpD,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK;YAC5C,CAAC,CAAC,SAAS,CAAC;IAClB,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,CAAC;IAEjE,OAAO,CACL,eACE,IAAI,EAAC,UAAU,EACf,SAAS,EAAE,EAAE,CACX,iHAAiH,CAClH,aAED,eAAK,SAAS,EAAC,wBAAwB,aACrC,eAAK,SAAS,EAAC,uCAAuC,aACpD,eAAM,SAAS,EAAC,8DAA8D,YAC3E,IAAI,GACA,EAGP,eAAM,SAAS,EAAC,8CAA8C,YAC3D,QAAQ,EAAE,KAAK,IAAI,YAAY,IAAI,EAAE,GACjC,IACH,EACN,eAAK,SAAS,EAAC,uCAAuC,aACnD,aAAa,IAAI,CAChB,eAAM,SAAS,EAAC,yEAAyE,YACtF,aAAa,GACT,CACR,EACA,SAAS,IAAI,CACZ,eAAM,SAAS,EAAC,2DAA2D,YACxE,aAAa,CAAC,SAAS,CAAC,CAAC,kBAAkB,EAAE,GACzC,CACR,IACG,IACF,EAEL,MAAM,IAAI,CACT,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,MAAM,gBACH,QAAQ,IAAI,EAAE,EAC1B,SAAS,EAAE,EAAE,CACX,+EAA+E,EAC/E,6DAA6D,CAC9D,YAED,KAAC,UAAU,KAAG,GACP,CACV,IACG,CACP,CAAC;AACJ,CAAC;AAED,SAAS,UAAU;IACjB,OAAO,CACL,cACE,KAAK,EAAC,IAAI,EACV,MAAM,EAAC,IAAI,EACX,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,KAAK,EACjB,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,iBACV,MAAM,YAElB,eAAM,CAAC,EAAC,oDAAoD,GAAG,GAC3D,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Channel-app copy shared by more than one surface, so the settings section
3
+ * and anything else that lists an organization's channel apps say the same
4
+ * thing.
5
+ *
6
+ * A channel app carries its organization's Slack or Meta app secrets, so the
7
+ * model shows it to its creator, anyone granted viewer on it and the
8
+ * organization's admins, and plain members and viewers may not see it at all
9
+ * (stigmer/stigmer#1384). An empty list is therefore not evidence that none
10
+ * is registered, so a caller who may not create channel apps is told who
11
+ * manages them instead of being told that nothing exists.
12
+ */
13
+ /** Shown in place of the empty state to a caller who may not create channel apps. */
14
+ export declare const CHANNEL_APPS_MANAGED_BY_ADMINS = "Channel apps are managed by your organization's admins.";
15
+ //# sourceMappingURL=copy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy.d.ts","sourceRoot":"","sources":["../src/channel-app/copy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,qFAAqF;AACrF,eAAO,MAAM,8BAA8B,4DACgB,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Channel-app copy shared by more than one surface, so the settings section
3
+ * and anything else that lists an organization's channel apps say the same
4
+ * thing.
5
+ *
6
+ * A channel app carries its organization's Slack or Meta app secrets, so the
7
+ * model shows it to its creator, anyone granted viewer on it and the
8
+ * organization's admins, and plain members and viewers may not see it at all
9
+ * (stigmer/stigmer#1384). An empty list is therefore not evidence that none
10
+ * is registered, so a caller who may not create channel apps is told who
11
+ * manages them instead of being told that nothing exists.
12
+ */
13
+ /** Shown in place of the empty state to a caller who may not create channel apps. */
14
+ export const CHANNEL_APPS_MANAGED_BY_ADMINS = "Channel apps are managed by your organization's admins.";
15
+ //# sourceMappingURL=copy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy.js","sourceRoot":"","sources":["../src/channel-app/copy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,qFAAqF;AACrF,MAAM,CAAC,MAAM,8BAA8B,GACzC,yDAAyD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stigmer/react",
3
- "version": "3.40.0",
3
+ "version": "3.40.1",
4
4
  "description": "React provider and client hook for the Stigmer platform SDK",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -37,8 +37,8 @@
37
37
  "dependencies": {
38
38
  "@bufbuild/protovalidate": "^1.1.1",
39
39
  "@dagrejs/dagre": "^1.1.4",
40
- "@stigmer/plugin-package": "3.40.0",
41
- "@stigmer/theme": "3.40.0",
40
+ "@stigmer/plugin-package": "3.40.1",
41
+ "@stigmer/theme": "3.40.1",
42
42
  "diff": "^8.0.3",
43
43
  "fflate": "^0.8.2",
44
44
  "hast-util-to-jsx-runtime": "^2.3.6",
@@ -61,8 +61,8 @@
61
61
  "@codemirror/state": "^6.0.0",
62
62
  "@codemirror/view": "^6.0.0",
63
63
  "@lezer/highlight": "^1.0.0",
64
- "@stigmer/protos": "3.40.0",
65
- "@stigmer/sdk": "3.40.0",
64
+ "@stigmer/protos": "3.40.1",
65
+ "@stigmer/sdk": "3.40.1",
66
66
  "@tanstack/react-table": "^8.20.0",
67
67
  "@xyflow/react": "^12.0.0",
68
68
  "elkjs": "^0.9.0",
@@ -8,6 +8,13 @@
8
8
  *
9
9
  * After registering an app here, the connect dialog on any agent's
10
10
  * Channels tab offers it as the serving app.
11
+ *
12
+ * "New channel app" is offered once the server confirms the caller holds
13
+ * `can_create_channel_app` on the organization. The list shows only the
14
+ * apps the caller may view (their creator, anyone granted viewer on one,
15
+ * and the organization's admins), so a caller who may not create channel
16
+ * apps is told that the organization's admins manage them rather than that
17
+ * none is registered.
11
18
  */
12
19
  export declare function ChannelAppsSection(): import("react/jsx-runtime").JSX.Element;
13
20
  //# sourceMappingURL=ChannelAppsSection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChannelAppsSection.d.ts","sourceRoot":"","sources":["../src/settings/ChannelAppsSection.tsx"],"names":[],"mappings":"AA4BA;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,4CA8FjC"}
1
+ {"version":3,"file":"ChannelAppsSection.d.ts","sourceRoot":"","sources":["../src/settings/ChannelAppsSection.tsx"],"names":[],"mappings":"AA8BA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,4CAsGjC"}
@@ -4,9 +4,11 @@ import { useCallback, useId, useRef, useState } from "react";
4
4
  import { ChannelAppListPanel } from "../channel-app/ChannelAppListPanel.js";
5
5
  import { CreateChannelAppForm, } from "../channel-app/CreateChannelAppForm.js";
6
6
  import { ChannelAppDetailPanel } from "../channel-app/ChannelAppDetailPanel.js";
7
+ import { CHANNEL_APPS_MANAGED_BY_ADMINS } from "../channel-app/copy.js";
7
8
  import { useDeploymentMode } from "../deployment-mode.js";
9
+ import { useCheckPermission } from "../iam-policy/useCheckPermission.js";
8
10
  import { CloudFeatureNotice } from "../internal/CloudFeatureNotice.js";
9
- import { useActiveOrgSlug } from "../organization/OrgProvider.js";
11
+ import { useActiveOrgId, useActiveOrgSlug } from "../organization/OrgProvider.js";
10
12
  /**
11
13
  * Settings section for the organization's channel apps — customer-owned
12
14
  * provider apps (Slack apps, Meta WhatsApp apps) that agent channels
@@ -17,13 +19,24 @@ import { useActiveOrgSlug } from "../organization/OrgProvider.js";
17
19
  *
18
20
  * After registering an app here, the connect dialog on any agent's
19
21
  * Channels tab offers it as the serving app.
22
+ *
23
+ * "New channel app" is offered once the server confirms the caller holds
24
+ * `can_create_channel_app` on the organization. The list shows only the
25
+ * apps the caller may view (their creator, anyone granted viewer on one,
26
+ * and the organization's admins), so a caller who may not create channel
27
+ * apps is told that the organization's admins manage them rather than that
28
+ * none is registered.
20
29
  */
21
30
  export function ChannelAppsSection() {
22
31
  const headingId = useId();
23
32
  const org = useActiveOrgSlug();
33
+ const orgId = useActiveOrgId();
24
34
  // Channel installs (the consumer of these credentials) are cloud-only;
25
35
  // gate the whole section the way the Channels tab gates connects.
26
36
  const installsAvailable = useDeploymentMode() === "cloud";
37
+ const createCheck = useCheckPermission(installsAvailable && orgId ? { kind: "organization", id: orgId } : null, "can_create_channel_app");
38
+ const canCreate = !createCheck.isLoading && createCheck.allowed;
39
+ const deniedCreate = !createCheck.isLoading && !createCheck.allowed;
27
40
  const [flow, setFlow] = useState({ phase: "idle" });
28
41
  const listRefetchRef = useRef(null);
29
42
  const handleRefetchRef = useCallback((refetch) => {
@@ -44,6 +57,6 @@ export function ChannelAppsSection() {
44
57
  listRefetchRef.current?.();
45
58
  setFlow({ phase: "idle" });
46
59
  }, []);
47
- return (_jsxs("section", { "aria-labelledby": headingId, children: [_jsxs("div", { className: "stg:mb-3 stg:flex stg:items-center stg:justify-between", children: [_jsx("h2", { id: headingId, className: "stg:text-foreground stg:text-sm stg:font-semibold", children: "Channel Apps" }), installsAvailable && org && flow.phase === "idle" && (_jsx("button", { type: "button", onClick: () => setFlow({ phase: "creating" }), className: "stg:text-primary stg:hover:text-foreground stg:text-xs stg:font-medium stg:transition-colors", children: "+ New channel app" }))] }), _jsx("p", { className: "stg:text-muted-foreground stg:mb-4 stg:text-xs", children: "Your own provider apps for serving agent channels. A Slack app gives the bot your name and icon, and lets multiple agents serve the same workspace \u2014 one per app. A Meta app is how WhatsApp channels connect \u2014 every WhatsApp channel installs through one." }), !installsAvailable ? (_jsx(CloudFeatureNotice, { children: "Channel apps are not available in local mode. Channel installs require Stigmer Cloud." })) : flow.phase === "creating" ? (_jsx("div", { className: "stg:border-border stg:bg-card stg:rounded-lg stg:border stg:p-4", children: _jsx(CreateChannelAppForm, { org: org, onCreated: handleCreated, onCancel: () => setFlow({ phase: "idle" }) }) })) : flow.phase === "editing" ? (_jsx("div", { className: "stg:border-border stg:bg-card stg:rounded-lg stg:border stg:p-4", children: _jsx(ChannelAppDetailPanel, { channelApp: flow.channelApp, createHandoff: flow.createHandoff, onUpdated: handleUpdated, onDeleted: handleDeleted, onBack: () => setFlow({ phase: "idle" }) }) })) : (_jsx(ChannelAppListPanel, { org: org, onEdit: (app) => setFlow({ phase: "editing", channelApp: app }), onRefetchRef: handleRefetchRef }))] }));
60
+ return (_jsxs("section", { "aria-labelledby": headingId, children: [_jsxs("div", { className: "stg:mb-3 stg:flex stg:items-center stg:justify-between", children: [_jsx("h2", { id: headingId, className: "stg:text-foreground stg:text-sm stg:font-semibold", children: "Channel Apps" }), installsAvailable && org && canCreate && flow.phase === "idle" && (_jsx("button", { type: "button", onClick: () => setFlow({ phase: "creating" }), className: "stg:text-primary stg:hover:text-foreground stg:text-xs stg:font-medium stg:transition-colors", children: "+ New channel app" }))] }), _jsx("p", { className: "stg:text-muted-foreground stg:mb-4 stg:text-xs", children: "Your own provider apps for serving agent channels. A Slack app gives the bot your name and icon, and lets multiple agents serve the same workspace \u2014 one per app. A Meta app is how WhatsApp channels connect \u2014 every WhatsApp channel installs through one." }), !installsAvailable ? (_jsx(CloudFeatureNotice, { children: "Channel apps are not available in local mode. Channel installs require Stigmer Cloud." })) : flow.phase === "creating" ? (_jsx("div", { className: "stg:border-border stg:bg-card stg:rounded-lg stg:border stg:p-4", children: _jsx(CreateChannelAppForm, { org: org, onCreated: handleCreated, onCancel: () => setFlow({ phase: "idle" }) }) })) : flow.phase === "editing" ? (_jsx("div", { className: "stg:border-border stg:bg-card stg:rounded-lg stg:border stg:p-4", children: _jsx(ChannelAppDetailPanel, { channelApp: flow.channelApp, createHandoff: flow.createHandoff, onUpdated: handleUpdated, onDeleted: handleDeleted, onBack: () => setFlow({ phase: "idle" }) }) })) : (_jsx(ChannelAppListPanel, { org: org, onEdit: (app) => setFlow({ phase: "editing", channelApp: app }), onRefetchRef: handleRefetchRef, emptyState: deniedCreate ? CHANNEL_APPS_MANAGED_BY_ADMINS : undefined }))] }));
48
61
  }
49
62
  //# sourceMappingURL=ChannelAppsSection.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChannelAppsSection.js","sourceRoot":"","sources":["../src/settings/ChannelAppsSection.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ChannelAppsSection.js","sourceRoot":"","sources":["../src/settings/ChannelAppsSection.tsx"],"names":[],"mappings":"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"}
@@ -18,6 +18,7 @@ import {
18
18
  whatsappChannelAppWebhookUrl,
19
19
  } from "./whatsappAppSetup.js";
20
20
  import { CopyBlock, CopyRow, FormField } from "./internal.js";
21
+ import { PermissionGate } from "../iam-policy/PermissionGate.js";
21
22
  import { SpinnerIcon } from "../internal/SpinnerIcon.js";
22
23
 
23
24
  // ---------------------------------------------------------------------------
@@ -66,6 +67,11 @@ export interface ChannelAppDetailPanelProps {
66
67
  * untouched preserves the stored values (rotate one secret without
67
68
  * re-entering the others). Deletion is refused server-side while any
68
69
  * agent channel still installs through this app.
70
+ *
71
+ * The credentials form is offered to a caller who may edit the app
72
+ * (`can_edit`) and the deletion section to one who may delete it
73
+ * (`can_delete`): its creator and the organization's admins. Someone
74
+ * granted viewer on an app sees its setup values with no actions.
69
75
  */
70
76
  export function ChannelAppDetailPanel({
71
77
  channelApp,
@@ -127,50 +133,55 @@ export function ChannelAppDetailPanel({
127
133
  ) : null}
128
134
 
129
135
  {/* Deletion */}
130
- <section className="stg:border-t stg:border-border stg:pt-3" aria-label="Danger zone">
131
- {deleteError && (
132
- <p className="stg:text-destructive stg:mb-2 stg:text-[0.65rem]" role="alert">
133
- {getUserMessage(deleteError)}
134
- </p>
135
- )}
136
- {confirmingDelete ? (
137
- <div className="stg:flex stg:items-center stg:gap-2">
138
- <p className="stg:text-xs stg:text-foreground">
139
- Delete this channel app? Channels installing through it must be
140
- disconnected first.
136
+ <PermissionGate
137
+ resource={{ kind: "channel_app", id: appId }}
138
+ relation="can_delete"
139
+ >
140
+ <section className="stg:border-t stg:border-border stg:pt-3" aria-label="Danger zone">
141
+ {deleteError && (
142
+ <p className="stg:text-destructive stg:mb-2 stg:text-[0.65rem]" role="alert">
143
+ {getUserMessage(deleteError)}
141
144
  </p>
145
+ )}
146
+ {confirmingDelete ? (
147
+ <div className="stg:flex stg:items-center stg:gap-2">
148
+ <p className="stg:text-xs stg:text-foreground">
149
+ Delete this channel app? Channels installing through it must be
150
+ disconnected first.
151
+ </p>
152
+ <button
153
+ type="button"
154
+ onClick={handleDelete}
155
+ disabled={isDeleting}
156
+ className={cn(
157
+ "stg:inline-flex stg:items-center stg:gap-1.5 stg:rounded-md stg:px-2.5 stg:py-1 stg:text-xs stg:font-medium",
158
+ "stg:bg-destructive stg:text-destructive-foreground stg:hover:opacity-90",
159
+ "stg:disabled:pointer-events-none stg:disabled:opacity-40",
160
+ )}
161
+ >
162
+ {isDeleting && <SpinnerIcon size={12} />}
163
+ Delete
164
+ </button>
165
+ <button
166
+ type="button"
167
+ onClick={() => setConfirmingDelete(false)}
168
+ disabled={isDeleting}
169
+ className="stg:text-muted-foreground stg:hover:text-foreground stg:text-xs stg:transition-colors"
170
+ >
171
+ Keep
172
+ </button>
173
+ </div>
174
+ ) : (
142
175
  <button
143
176
  type="button"
144
- onClick={handleDelete}
145
- disabled={isDeleting}
146
- className={cn(
147
- "stg:inline-flex stg:items-center stg:gap-1.5 stg:rounded-md stg:px-2.5 stg:py-1 stg:text-xs stg:font-medium",
148
- "stg:bg-destructive stg:text-destructive-foreground stg:hover:opacity-90",
149
- "stg:disabled:pointer-events-none stg:disabled:opacity-40",
150
- )}
151
- >
152
- {isDeleting && <SpinnerIcon size={12} />}
153
- Delete
154
- </button>
155
- <button
156
- type="button"
157
- onClick={() => setConfirmingDelete(false)}
158
- disabled={isDeleting}
159
- className="stg:text-muted-foreground stg:hover:text-foreground stg:text-xs stg:transition-colors"
177
+ onClick={() => setConfirmingDelete(true)}
178
+ className="stg:text-destructive stg:text-xs stg:font-medium stg:hover:opacity-80"
160
179
  >
161
- Keep
180
+ Delete channel app
162
181
  </button>
163
- </div>
164
- ) : (
165
- <button
166
- type="button"
167
- onClick={() => setConfirmingDelete(true)}
168
- className="stg:text-destructive stg:text-xs stg:font-medium stg:hover:opacity-80"
169
- >
170
- Delete channel app
171
- </button>
172
- )}
173
- </section>
182
+ )}
183
+ </section>
184
+ </PermissionGate>
174
185
  </div>
175
186
  );
176
187
  }
@@ -270,63 +281,68 @@ function SlackAppDetail({
270
281
  </section>
271
282
 
272
283
  {/* Credential rotation */}
273
- <form onSubmit={handleSave} className="stg:space-y-3" aria-label="Credentials">
274
- <p className="stg:text-xs stg:font-medium stg:text-foreground">Credentials</p>
275
- <p className="stg:-mt-2 stg:text-[0.65rem] stg:text-muted-foreground">
276
- Secrets show as <code className="stg:font-mono">***REDACTED***</code>;
277
- leave a field untouched to keep its stored value, or paste a new
278
- one to rotate it.
279
- </p>
280
-
281
- <FormField
282
- id={`${baseId}-client-id`}
283
- label="Client ID"
284
- value={clientId}
285
- onChange={setClientId}
286
- placeholder="1234567890.0987654321"
287
- disabled={isUpdating}
288
- required
289
- />
290
- <FormField
291
- id={`${baseId}-client-secret`}
292
- label="Client secret"
293
- value={clientSecret}
294
- onChange={setClientSecret}
295
- placeholder="Client secret"
296
- type="password"
297
- disabled={isUpdating}
298
- required
299
- />
300
- <FormField
301
- id={`${baseId}-signing-secret`}
302
- label="Signing secret"
303
- value={signingSecret}
304
- onChange={setSigningSecret}
305
- placeholder="Signing secret"
306
- type="password"
307
- disabled={isUpdating}
308
- required
309
- />
310
-
311
- {updateError && (
312
- <p className="stg:text-destructive stg:text-[0.65rem]" role="alert">
313
- {getUserMessage(updateError)}
284
+ <PermissionGate
285
+ resource={{ kind: "channel_app", id: appId }}
286
+ relation="can_edit"
287
+ >
288
+ <form onSubmit={handleSave} className="stg:space-y-3" aria-label="Credentials">
289
+ <p className="stg:text-xs stg:font-medium stg:text-foreground">Credentials</p>
290
+ <p className="stg:-mt-2 stg:text-[0.65rem] stg:text-muted-foreground">
291
+ Secrets show as <code className="stg:font-mono">***REDACTED***</code>;
292
+ leave a field untouched to keep its stored value, or paste a new
293
+ one to rotate it.
314
294
  </p>
315
- )}
316
295
 
317
- <button
318
- type="submit"
319
- disabled={!canSave}
320
- className={cn(
321
- "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",
322
- "stg:bg-primary stg:text-primary-foreground stg:hover:bg-primary-hover",
323
- "stg:disabled:pointer-events-none stg:disabled:opacity-40",
296
+ <FormField
297
+ id={`${baseId}-client-id`}
298
+ label="Client ID"
299
+ value={clientId}
300
+ onChange={setClientId}
301
+ placeholder="1234567890.0987654321"
302
+ disabled={isUpdating}
303
+ required
304
+ />
305
+ <FormField
306
+ id={`${baseId}-client-secret`}
307
+ label="Client secret"
308
+ value={clientSecret}
309
+ onChange={setClientSecret}
310
+ placeholder="Client secret"
311
+ type="password"
312
+ disabled={isUpdating}
313
+ required
314
+ />
315
+ <FormField
316
+ id={`${baseId}-signing-secret`}
317
+ label="Signing secret"
318
+ value={signingSecret}
319
+ onChange={setSigningSecret}
320
+ placeholder="Signing secret"
321
+ type="password"
322
+ disabled={isUpdating}
323
+ required
324
+ />
325
+
326
+ {updateError && (
327
+ <p className="stg:text-destructive stg:text-[0.65rem]" role="alert">
328
+ {getUserMessage(updateError)}
329
+ </p>
324
330
  )}
325
- >
326
- {isUpdating && <SpinnerIcon size={12} />}
327
- Save credentials
328
- </button>
329
- </form>
331
+
332
+ <button
333
+ type="submit"
334
+ disabled={!canSave}
335
+ className={cn(
336
+ "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",
337
+ "stg:bg-primary stg:text-primary-foreground stg:hover:bg-primary-hover",
338
+ "stg:disabled:pointer-events-none stg:disabled:opacity-40",
339
+ )}
340
+ >
341
+ {isUpdating && <SpinnerIcon size={12} />}
342
+ Save credentials
343
+ </button>
344
+ </form>
345
+ </PermissionGate>
330
346
  </>
331
347
  );
332
348
  }
@@ -440,74 +456,79 @@ function WhatsAppAppDetail({
440
456
  </section>
441
457
 
442
458
  {/* Credential rotation */}
443
- <form onSubmit={handleSave} className="stg:space-y-3" aria-label="Credentials">
444
- <p className="stg:text-xs stg:font-medium stg:text-foreground">Credentials</p>
445
- <p className="stg:-mt-2 stg:text-[0.65rem] stg:text-muted-foreground">
446
- Secrets show as <code className="stg:font-mono">***REDACTED***</code>;
447
- leave a field untouched to keep its stored value, or paste a new
448
- one to rotate it.
449
- </p>
450
-
451
- <FormField
452
- id={`${baseId}-app-id`}
453
- label="App ID"
454
- value={metaAppId}
455
- onChange={setMetaAppId}
456
- placeholder="1234567890123456"
457
- disabled={isUpdating}
458
- required
459
- />
460
- <FormField
461
- id={`${baseId}-app-secret`}
462
- label="App secret"
463
- value={appSecret}
464
- onChange={setAppSecret}
465
- placeholder="App secret"
466
- type="password"
467
- disabled={isUpdating}
468
- required
469
- />
470
- <FormField
471
- id={`${baseId}-access-token`}
472
- label="Access token"
473
- value={accessToken}
474
- onChange={setAccessToken}
475
- placeholder="Long-lived system-user access token"
476
- type="password"
477
- disabled={isUpdating}
478
- required
479
- />
480
- <FormField
481
- id={`${baseId}-verify-token`}
482
- label="Verify token"
483
- value={verifyToken}
484
- onChange={setVerifyToken}
485
- placeholder="Verify token"
486
- type="password"
487
- hint="Rotating it? Update Meta's webhook configuration to the same value."
488
- disabled={isUpdating}
489
- required
490
- />
491
-
492
- {updateError && (
493
- <p className="stg:text-destructive stg:text-[0.65rem]" role="alert">
494
- {getUserMessage(updateError)}
459
+ <PermissionGate
460
+ resource={{ kind: "channel_app", id: appId }}
461
+ relation="can_edit"
462
+ >
463
+ <form onSubmit={handleSave} className="stg:space-y-3" aria-label="Credentials">
464
+ <p className="stg:text-xs stg:font-medium stg:text-foreground">Credentials</p>
465
+ <p className="stg:-mt-2 stg:text-[0.65rem] stg:text-muted-foreground">
466
+ Secrets show as <code className="stg:font-mono">***REDACTED***</code>;
467
+ leave a field untouched to keep its stored value, or paste a new
468
+ one to rotate it.
495
469
  </p>
496
- )}
497
470
 
498
- <button
499
- type="submit"
500
- disabled={!canSave}
501
- className={cn(
502
- "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",
503
- "stg:bg-primary stg:text-primary-foreground stg:hover:bg-primary-hover",
504
- "stg:disabled:pointer-events-none stg:disabled:opacity-40",
471
+ <FormField
472
+ id={`${baseId}-app-id`}
473
+ label="App ID"
474
+ value={metaAppId}
475
+ onChange={setMetaAppId}
476
+ placeholder="1234567890123456"
477
+ disabled={isUpdating}
478
+ required
479
+ />
480
+ <FormField
481
+ id={`${baseId}-app-secret`}
482
+ label="App secret"
483
+ value={appSecret}
484
+ onChange={setAppSecret}
485
+ placeholder="App secret"
486
+ type="password"
487
+ disabled={isUpdating}
488
+ required
489
+ />
490
+ <FormField
491
+ id={`${baseId}-access-token`}
492
+ label="Access token"
493
+ value={accessToken}
494
+ onChange={setAccessToken}
495
+ placeholder="Long-lived system-user access token"
496
+ type="password"
497
+ disabled={isUpdating}
498
+ required
499
+ />
500
+ <FormField
501
+ id={`${baseId}-verify-token`}
502
+ label="Verify token"
503
+ value={verifyToken}
504
+ onChange={setVerifyToken}
505
+ placeholder="Verify token"
506
+ type="password"
507
+ hint="Rotating it? Update Meta's webhook configuration to the same value."
508
+ disabled={isUpdating}
509
+ required
510
+ />
511
+
512
+ {updateError && (
513
+ <p className="stg:text-destructive stg:text-[0.65rem]" role="alert">
514
+ {getUserMessage(updateError)}
515
+ </p>
505
516
  )}
506
- >
507
- {isUpdating && <SpinnerIcon size={12} />}
508
- Save credentials
509
- </button>
510
- </form>
517
+
518
+ <button
519
+ type="submit"
520
+ disabled={!canSave}
521
+ className={cn(
522
+ "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",
523
+ "stg:bg-primary stg:text-primary-foreground stg:hover:bg-primary-hover",
524
+ "stg:disabled:pointer-events-none stg:disabled:opacity-40",
525
+ )}
526
+ >
527
+ {isUpdating && <SpinnerIcon size={12} />}
528
+ Save credentials
529
+ </button>
530
+ </form>
531
+ </PermissionGate>
511
532
  </>
512
533
  );
513
534
  }
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
 
3
+ import type { ReactNode } from "react";
3
4
  import { cn } from "@stigmer/theme";
4
5
  import { getUserMessage } from "@stigmer/sdk";
5
6
  import { timestampDate } from "@bufbuild/protobuf/wkt";
@@ -22,14 +23,22 @@ export interface ChannelAppListPanelProps {
22
23
  readonly onEdit?: (app: ChannelApp) => void;
23
24
  /** Re-expose refetch so parents can trigger a list refresh. */
24
25
  readonly onRefetchRef?: (refetch: () => void) => void;
26
+ /**
27
+ * Shown when the list is empty. Defaults to "No channel apps registered
28
+ * yet." The list holds only the apps the caller may view (their creator,
29
+ * anyone granted viewer on one, and the organization's admins), so a host
30
+ * that knows the caller may not manage channel apps should say who does
31
+ * instead.
32
+ */
33
+ readonly emptyState?: ReactNode;
25
34
  /** Additional CSS class names for the root container. */
26
35
  readonly className?: string;
27
36
  }
28
37
 
29
38
  /**
30
- * Displays the {@link ChannelApp} resources owned by an organization —
31
- * the customer's own provider apps (Slack, Meta/WhatsApp) that agent
32
- * channels can install through.
39
+ * Displays the {@link ChannelApp} resources of an organization that the
40
+ * caller may view — the customer's own provider apps (Slack,
41
+ * Meta/WhatsApp) that agent channels can install through.
33
42
  *
34
43
  * Each row shows the app name, provider, the provider's non-secret app
35
44
  * identifier, and creation date. Secret fields never appear (they
@@ -49,6 +58,7 @@ export function ChannelAppListPanel({
49
58
  org,
50
59
  onEdit,
51
60
  onRefetchRef,
61
+ emptyState = "No channel apps registered yet.",
52
62
  className,
53
63
  }: ChannelAppListPanelProps) {
54
64
  const { channelApps, isLoading, error, refetch } = useChannelAppList(org);
@@ -87,7 +97,7 @@ export function ChannelAppListPanel({
87
97
  className,
88
98
  )}
89
99
  >
90
- No channel apps registered yet.
100
+ {emptyState}
91
101
  </p>
92
102
  );
93
103
  }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Channel-app copy shared by more than one surface, so the settings section
3
+ * and anything else that lists an organization's channel apps say the same
4
+ * thing.
5
+ *
6
+ * A channel app carries its organization's Slack or Meta app secrets, so the
7
+ * model shows it to its creator, anyone granted viewer on it and the
8
+ * organization's admins, and plain members and viewers may not see it at all
9
+ * (stigmer/stigmer#1384). An empty list is therefore not evidence that none
10
+ * is registered, so a caller who may not create channel apps is told who
11
+ * manages them instead of being told that nothing exists.
12
+ */
13
+
14
+ /** Shown in place of the empty state to a caller who may not create channel apps. */
15
+ export const CHANNEL_APPS_MANAGED_BY_ADMINS =
16
+ "Channel apps are managed by your organization's admins.";
@@ -8,9 +8,11 @@ import {
8
8
  type ChannelAppCreateHandoff,
9
9
  } from "../channel-app/CreateChannelAppForm.js";
10
10
  import { ChannelAppDetailPanel } from "../channel-app/ChannelAppDetailPanel.js";
11
+ import { CHANNEL_APPS_MANAGED_BY_ADMINS } from "../channel-app/copy.js";
11
12
  import { useDeploymentMode } from "../deployment-mode.js";
13
+ import { useCheckPermission } from "../iam-policy/useCheckPermission.js";
12
14
  import { CloudFeatureNotice } from "../internal/CloudFeatureNotice.js";
13
- import { useActiveOrgSlug } from "../organization/OrgProvider.js";
15
+ import { useActiveOrgId, useActiveOrgSlug } from "../organization/OrgProvider.js";
14
16
 
15
17
  type FlowState =
16
18
  | { phase: "idle" }
@@ -36,13 +38,27 @@ type FlowState =
36
38
  *
37
39
  * After registering an app here, the connect dialog on any agent's
38
40
  * Channels tab offers it as the serving app.
41
+ *
42
+ * "New channel app" is offered once the server confirms the caller holds
43
+ * `can_create_channel_app` on the organization. The list shows only the
44
+ * apps the caller may view (their creator, anyone granted viewer on one,
45
+ * and the organization's admins), so a caller who may not create channel
46
+ * apps is told that the organization's admins manage them rather than that
47
+ * none is registered.
39
48
  */
40
49
  export function ChannelAppsSection() {
41
50
  const headingId = useId();
42
51
  const org = useActiveOrgSlug();
52
+ const orgId = useActiveOrgId();
43
53
  // Channel installs (the consumer of these credentials) are cloud-only;
44
54
  // gate the whole section the way the Channels tab gates connects.
45
55
  const installsAvailable = useDeploymentMode() === "cloud";
56
+ const createCheck = useCheckPermission(
57
+ installsAvailable && orgId ? { kind: "organization", id: orgId } : null,
58
+ "can_create_channel_app",
59
+ );
60
+ const canCreate = !createCheck.isLoading && createCheck.allowed;
61
+ const deniedCreate = !createCheck.isLoading && !createCheck.allowed;
46
62
 
47
63
  const [flow, setFlow] = useState<FlowState>({ phase: "idle" });
48
64
  const listRefetchRef = useRef<(() => void) | null>(null);
@@ -82,7 +98,7 @@ export function ChannelAppsSection() {
82
98
  Channel Apps
83
99
  </h2>
84
100
 
85
- {installsAvailable && org && flow.phase === "idle" && (
101
+ {installsAvailable && org && canCreate && flow.phase === "idle" && (
86
102
  <button
87
103
  type="button"
88
104
  onClick={() => setFlow({ phase: "creating" })}
@@ -127,6 +143,7 @@ export function ChannelAppsSection() {
127
143
  org={org}
128
144
  onEdit={(app) => setFlow({ phase: "editing", channelApp: app })}
129
145
  onRefetchRef={handleRefetchRef}
146
+ emptyState={deniedCreate ? CHANNEL_APPS_MANAGED_BY_ADMINS : undefined}
130
147
  />
131
148
  )}
132
149
  </section>