@ambitresearch/paperclip-agent-identities 0.2.3
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/LICENSE +21 -0
- package/README.md +287 -0
- package/dist/manifest.js +6778 -0
- package/dist/manifest.js.map +7 -0
- package/dist/ui/index.js +3360 -0
- package/dist/ui/index.js.map +7 -0
- package/dist/worker.js +17962 -0
- package/dist/worker.js.map +7 -0
- package/package.json +61 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/ui/index.tsx", "../../src/ui/theme.ts", "../../src/ui/SettingsPage.tsx", "../../src/shared/types.ts", "../../src/shared/slack-bot-whoami-tool.ts", "../../src/core/provider-settings-contract.ts", "../../src/providers/github/settings-adapter.ts", "../../src/providers/slack/settings-adapter.ts", "../../src/providers/settings-index.ts", "../../src/core/provider-settings-ui-contract.ts", "../../src/providers/slack/settings-adapter-ui.tsx", "../../src/providers/github/settings-adapter-ui.tsx", "../../src/providers/settings-ui-index.ts"],
|
|
4
|
+
"sourcesContent": ["import { usePluginData, type PluginWidgetProps } from \"@paperclipai/plugin-sdk/ui\";\nimport {\n createPaperclipThemeStyle,\n uiBorderStrong,\n uiMutedText,\n uiPanel,\n uiSuccess,\n uiWarning,\n usePaperclipThemeMode,\n} from \"./theme.js\";\nimport type { BotIdentitySettingsData, BotIdentitySettingsEntry } from \"../shared/types.js\";\n\nexport function DashboardWidget({ context }: PluginWidgetProps) {\n const themeMode = usePaperclipThemeMode();\n const { data, loading, error } = usePluginData<BotIdentitySettingsData>(\"bot-identity-config\", {\n companyId: context.companyId,\n });\n\n if (loading) return <div>Loading agent identities...</div>;\n if (error) return <div>Agent identities unavailable: {error.message}</div>;\n\n const identities = data?.identities ?? [];\n const summary = summarizeIdentities(identities);\n\n return (\n <div style={{ ...createPaperclipThemeStyle(themeMode), ...widgetStyle }} data-agent-identities-theme={themeMode}>\n <div>\n <strong>Agent Identities</strong>\n <div style={mutedStyle}>Identity provider coverage</div>\n </div>\n\n <div style={metricGridStyle}>\n <Metric label=\"Identities\" value={summary.total} tone=\"neutral\" />\n <Metric label=\"GitHub Apps\" value={summary.githubApps} tone={summary.githubApps > 0 ? \"good\" : \"neutral\"} />\n <Metric label=\"Need setup\" value={summary.needsSetup} tone={summary.needsSetup > 0 ? \"warn\" : \"good\"} />\n </div>\n\n {data?.credentialSidecarError && (\n <div style={warningStyle}>GitHub credential sidecar unavailable. GitHub saves may not update private key references.</div>\n )}\n\n {identities.length === 0 ? (\n <div style={hintBoxStyle}>No agent identities configured yet. Open plugin settings to add a provider-backed agent identity.</div>\n ) : (\n <div style={identityListStyle}>\n {identities.slice(0, 3).map((identity) => (\n <div key={identity.id} style={identityRowStyle}>\n <div style={{ minWidth: 0 }}>\n <div style={identityNameStyle}>{identity.label}</div>\n <div style={mutedStyle}>{formatProviderIdentity(identity)}</div>\n </div>\n <span style={badgeStyle(identityTone(identity))}>{formatIdentityCredential(identity)}</span>\n </div>\n ))}\n {identities.length > 3 && <div style={mutedStyle}>+{identities.length - 3} more configured</div>}\n </div>\n )}\n </div>\n );\n}\n\nexport { SettingsPage } from \"./SettingsPage.js\";\n\nfunction summarizeIdentities(identities: BotIdentitySettingsEntry[]) {\n const githubApps = identities.filter((identity) => hasCompleteGitHubApp(identity)).length;\n return {\n total: identities.length,\n githubApps,\n needsSetup: identities.filter((identity) => identity.credentialStatus !== \"configured\").length,\n };\n}\n\nfunction hasCompleteGitHubApp(identity: BotIdentitySettingsEntry): boolean {\n const githubApp = identity.credential?.githubApp;\n return Boolean(githubApp?.appId && githubApp.installationId && (githubApp.privateKeySecretId || githubApp.privateKeyFile));\n}\n\nfunction hasFallbackCredential(identity: BotIdentitySettingsEntry): boolean {\n return Boolean(identity.credential?.secretId || identity.credential?.tokenFile);\n}\n\nfunction formatProviderIdentity(identity: BotIdentitySettingsEntry): string {\n if (identity.provider === \"github\") return `GitHub: ${identity.github.username}`;\n if (identity.provider === \"slack\") return `Slack: ${identity.slack.teamId}`;\n return identity.provider;\n}\n\nfunction formatIdentityCredential(identity: BotIdentitySettingsEntry): string {\n if (hasCompleteGitHubApp(identity)) return \"GitHub App\";\n if (hasFallbackCredential(identity)) return \"Fallback\";\n if (identity.credentialStatus === \"configured\") return \"Configured\";\n if (identity.credentialStatus === \"rebind-required\") return \"Rebind required\";\n if (identity.credentialStatus === \"cleanup-pending\") return \"Cleanup pending\";\n if (identity.credentialStatus === \"conflict\") return \"Conflict\";\n if (identity.credentialStatus === \"sidecar-unavailable\") return \"Unavailable\";\n return \"Missing\";\n}\n\nfunction identityTone(identity: BotIdentitySettingsEntry): MetricTone {\n if (hasCompleteGitHubApp(identity)) return \"good\";\n if (hasFallbackCredential(identity)) return \"neutral\";\n if (identity.credentialStatus === \"configured\") return \"good\";\n return \"warn\";\n}\n\ntype MetricTone = \"good\" | \"neutral\" | \"warn\";\n\nfunction Metric(props: { label: string; value: number; tone: MetricTone }) {\n return (\n <div style={metricStyle(props.tone)}>\n <div style={metricValueStyle}>{props.value}</div>\n <div style={metricLabelStyle}>{props.label}</div>\n </div>\n );\n}\n\nconst widgetStyle = {\n display: \"grid\",\n gap: \"0.75rem\",\n} as const;\n\nconst mutedStyle = {\n color: uiMutedText,\n fontSize: \"0.85rem\",\n overflowWrap: \"anywhere\",\n} as const;\n\nconst metricGridStyle = {\n display: \"grid\",\n gridTemplateColumns: \"repeat(3, minmax(0, 1fr))\",\n gap: \"0.5rem\",\n} as const;\n\nfunction metricStyle(tone: MetricTone) {\n return {\n border: `1px solid ${toneColor(tone)}`,\n borderRadius: 8,\n padding: \"0.6rem\",\n background: toneBackground(tone),\n } as const;\n}\n\nconst metricValueStyle = {\n fontSize: \"1.35rem\",\n fontWeight: 700,\n lineHeight: 1,\n} as const;\n\nconst metricLabelStyle = {\n color: uiMutedText,\n fontSize: \"0.75rem\",\n marginTop: \"0.25rem\",\n} as const;\n\nconst identityListStyle = {\n display: \"grid\",\n gap: \"0.45rem\",\n} as const;\n\nconst identityRowStyle = {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n gap: \"0.75rem\",\n} as const;\n\nconst identityNameStyle = {\n fontWeight: 600,\n overflowWrap: \"anywhere\",\n} as const;\n\nfunction badgeStyle(tone: MetricTone) {\n return {\n border: `1px solid ${toneColor(tone)}`,\n borderRadius: 999,\n padding: \"0.15rem 0.5rem\",\n color: toneColor(tone),\n fontSize: \"0.75rem\",\n whiteSpace: \"nowrap\",\n } as const;\n}\n\nconst hintBoxStyle = {\n border: `1px dashed ${uiBorderStrong}`,\n borderRadius: 8,\n padding: \"0.65rem\",\n color: uiMutedText,\n fontSize: \"0.9rem\",\n} as const;\n\nconst warningStyle = {\n border: `1px solid ${uiWarning}`,\n borderRadius: 8,\n padding: \"0.65rem\",\n color: uiWarning,\n background: \"color-mix(in srgb, var(--agent-identities-warning) 12%, transparent)\",\n fontSize: \"0.9rem\",\n} as const;\n\nfunction toneColor(tone: MetricTone): string {\n if (tone === \"good\") return uiSuccess;\n if (tone === \"warn\") return uiWarning;\n return uiMutedText;\n}\n\nfunction toneBackground(tone: MetricTone): string {\n if (tone === \"good\") return \"color-mix(in srgb, var(--agent-identities-success) 10%, transparent)\";\n if (tone === \"warn\") return \"color-mix(in srgb, var(--agent-identities-warning) 12%, transparent)\";\n return uiPanel;\n}\n", "import { useEffect, useState, type CSSProperties } from \"react\";\n\nexport type PaperclipThemeMode = \"light\" | \"dark\";\n\ntype AgentIdentitiesThemeVars = CSSProperties & Record<`--agent-identities-${string}`, string>;\n\nexport const uiSurface = \"var(--agent-identities-surface)\";\nexport const uiCanvas = \"var(--agent-identities-canvas)\";\nexport const uiPanel = \"var(--agent-identities-panel)\";\nexport const uiMutedPanel = \"var(--agent-identities-muted-panel)\";\nexport const uiInput = \"var(--agent-identities-input)\";\nexport const uiBorder = \"var(--agent-identities-border)\";\nexport const uiBorderStrong = \"var(--agent-identities-border-strong)\";\nexport const uiText = \"var(--agent-identities-text)\";\nexport const uiMutedText = \"var(--agent-identities-muted-text)\";\nexport const uiPrimary = \"var(--agent-identities-primary)\";\nexport const uiPrimaryText = \"var(--agent-identities-primary-text)\";\nexport const uiLink = \"var(--agent-identities-link)\";\nexport const uiSuccess = \"var(--agent-identities-success)\";\nexport const uiWarning = \"var(--agent-identities-warning)\";\nexport const uiDanger = \"var(--agent-identities-danger)\";\nexport const uiOverlay = \"var(--agent-identities-overlay)\";\nexport const uiShadow = \"var(--agent-identities-shadow)\";\n\nexport function createPaperclipThemeStyle(mode: PaperclipThemeMode): AgentIdentitiesThemeVars {\n return mode === \"dark\" ? darkThemeVars : lightThemeVars;\n}\n\nexport function usePaperclipThemeMode(): PaperclipThemeMode {\n const [mode, setMode] = useState<PaperclipThemeMode>(() => detectPaperclipThemeMode());\n\n useEffect(() => {\n const updateMode = () => setMode(detectPaperclipThemeMode());\n const observedDocuments = [document, getSameOriginParentDocument()].filter((doc): doc is Document => Boolean(doc));\n const observers = observedDocuments.flatMap((doc) => {\n const targets = [doc.documentElement, doc.body].filter((target): target is HTMLElement => Boolean(target));\n return targets.map((target) => {\n const observer = new MutationObserver(updateMode);\n observer.observe(target, { attributes: true, attributeFilter: [\"class\", \"data-theme\", \"style\"] });\n return observer;\n });\n });\n const mediaQuery = window.matchMedia?.(\"(prefers-color-scheme: dark)\");\n\n mediaQuery?.addEventListener?.(\"change\", updateMode);\n updateMode();\n\n return () => {\n observers.forEach((observer) => observer.disconnect());\n mediaQuery?.removeEventListener?.(\"change\", updateMode);\n };\n }, []);\n\n return mode;\n}\n\nfunction detectPaperclipThemeMode(): PaperclipThemeMode {\n if (typeof document === \"undefined\") return \"light\";\n\n const documents = [document, getSameOriginParentDocument()].filter((doc): doc is Document => Boolean(doc));\n for (const doc of documents) {\n const explicitMode = getExplicitThemeMode(doc.documentElement) ?? getExplicitThemeMode(doc.body);\n if (explicitMode) return explicitMode;\n }\n\n if (window.matchMedia?.(\"(prefers-color-scheme: dark)\").matches) return \"dark\";\n return \"light\";\n}\n\nfunction getExplicitThemeMode(element: HTMLElement | null): PaperclipThemeMode | null {\n if (!element) return null;\n const theme = element.dataset.theme?.toLowerCase();\n if (theme === \"dark\") return \"dark\";\n if (theme === \"light\") return \"light\";\n if (element.classList.contains(\"dark\") || element.classList.contains(\"dark-theme\")) return \"dark\";\n if (element.classList.contains(\"light\") || element.classList.contains(\"light-theme\")) return \"light\";\n if (element.style.colorScheme === \"dark\") return \"dark\";\n if (element.style.colorScheme === \"light\") return \"light\";\n return null;\n}\n\nfunction getSameOriginParentDocument(): Document | null {\n if (typeof window === \"undefined\" || window.parent === window) return null;\n try {\n return window.parent.document;\n } catch {\n return null;\n }\n}\n\nconst lightThemeVars: AgentIdentitiesThemeVars = {\n colorScheme: \"light\",\n \"--agent-identities-surface\": \"oklch(100% 0 0)\",\n \"--agent-identities-canvas\": \"oklch(100% 0 0)\",\n \"--agent-identities-panel\": \"oklch(97% 0 0)\",\n \"--agent-identities-muted-panel\": \"oklch(92.2% 0 0)\",\n \"--agent-identities-input\": \"oklch(100% 0 0)\",\n \"--agent-identities-border\": \"oklch(92.2% 0 0)\",\n \"--agent-identities-border-strong\": \"oklch(70.8% 0 0)\",\n \"--agent-identities-text\": \"oklch(14.5% 0 0)\",\n \"--agent-identities-muted-text\": \"oklch(55.6% 0 0)\",\n \"--agent-identities-primary\": \"oklch(20.5% 0 0)\",\n \"--agent-identities-primary-text\": \"oklch(98.5% 0 0)\",\n \"--agent-identities-link\": \"oklch(42% 0.16 264)\",\n \"--agent-identities-success\": \"oklch(52.7% 0.154 150.069)\",\n \"--agent-identities-warning\": \"oklch(55.5% 0.163 48.998)\",\n \"--agent-identities-danger\": \"oklch(57.7% 0.245 27.325)\",\n \"--agent-identities-overlay\": \"oklch(0% 0 0 / 42%)\",\n \"--agent-identities-shadow\": \"oklch(0% 0 0 / 18%)\",\n};\n\nconst darkThemeVars: AgentIdentitiesThemeVars = {\n colorScheme: \"dark\",\n \"--agent-identities-surface\": \"oklch(20.5% 0 0)\",\n \"--agent-identities-canvas\": \"oklch(20.5% 0 0)\",\n \"--agent-identities-panel\": \"oklch(26.9% 0 0)\",\n \"--agent-identities-muted-panel\": \"oklch(35% 0 0)\",\n \"--agent-identities-input\": \"oklch(26.9% 0 0)\",\n \"--agent-identities-border\": \"oklch(35% 0 0)\",\n \"--agent-identities-border-strong\": \"oklch(43.9% 0 0)\",\n \"--agent-identities-text\": \"oklch(98.5% 0 0)\",\n \"--agent-identities-muted-text\": \"oklch(70.8% 0 0)\",\n \"--agent-identities-primary\": \"oklch(98.5% 0 0)\",\n \"--agent-identities-primary-text\": \"oklch(20.5% 0 0)\",\n \"--agent-identities-link\": \"oklch(78% 0.12 264)\",\n \"--agent-identities-success\": \"oklch(72.3% 0.219 149.579)\",\n \"--agent-identities-warning\": \"oklch(85.2% 0.199 91.936)\",\n \"--agent-identities-danger\": \"oklch(70.4% 0.191 22.216)\",\n \"--agent-identities-overlay\": \"oklch(0% 0 0 / 58%)\",\n \"--agent-identities-shadow\": \"oklch(0% 0 0 / 45%)\",\n};\n", "import { useEffect, useRef, useState, type CSSProperties } from \"react\";\nimport { usePluginData, usePluginAction, type PluginSettingsPageProps } from \"@paperclipai/plugin-sdk/ui\";\nimport { DEFAULT_BOT_IDENTITY_CONFIG, GITHUB_IDENTITY_PROVIDER_ID, REBIND_LEGACY_SLACK_CREDENTIALS_ACTION, SLACK_IDENTITY_PROVIDER_ID, isIdentityProviderId } from \"../shared/types.js\";\nimport { slackBotWhoamiToolName } from \"../shared/slack-bot-whoami-tool.js\";\nimport { buildProviderSettingsRegistry } from \"../core/provider-settings-contract.js\";\nimport { ALL_SETTINGS_ADAPTERS } from \"../providers/settings-index.js\";\nimport { providerSettingsUIRegistry } from \"../providers/settings-ui-index.js\";\nimport {\n createPaperclipThemeStyle,\n uiBorder,\n uiBorderStrong,\n uiCanvas,\n uiDanger,\n uiInput,\n uiLink,\n uiMutedText,\n uiOverlay,\n uiPanel,\n uiPrimary,\n uiPrimaryText,\n uiShadow,\n uiSuccess,\n uiSurface,\n uiText,\n uiWarning,\n usePaperclipThemeMode,\n} from \"./theme.js\";\nimport type {\n BotIdentitySettingsData,\n BotIdentitySettingsEntry,\n PaperclipAgentOption,\n PaperclipAgentsData,\n SaveBotIdentityConfigInput,\n SaveSlackInstallMetadataResult\n} from \"../shared/types.js\";\n\ntype PaperclipSecretOption = {\n id: string;\n name: string;\n key?: string;\n description?: string;\n provider?: string;\n status?: string;\n};\n\nexport type IdentityFormState = {\n agentId: string;\n provider: string;\n label: string;\n githubUsername: string;\n commitName: string;\n commitEmail: string;\n githubAppId: string;\n githubInstallationId: string;\n privateKeySecretId: string;\n privateKeyFile: string;\n fallbackTokenSecretId: string;\n tokenFile: string;\n previousAgentId: string;\n previousGithubAppId: string;\n previousGithubInstallationId: string;\n previousPrivateKeySecretId: string;\n previousPrivateKeyFile: string;\n slackTeamId: string;\n slackAppId: string;\n slackBotUserId: string;\n slackDefaultChannel: string;\n slackEventsRequestUrl: string;\n slackBotTokenSecretId: string;\n slackSigningSecretId: string;\n slackLegacyCredentialStatus: string;\n slackLegacySigningSecretRequired: string;\n};\n\ntype IdentityFormSection = \"identity\" | \"github\" | \"slack\" | \"commit\";\ntype IdentityFormValidation = {\n identityComplete: boolean;\n credentialComplete: boolean;\n isComplete: boolean;\n identityMessage: string;\n credentialMessage: string;\n saveMessage: string;\n};\ntype IdentityTone = \"good\" | \"warn\" | \"neutral\";\n\nexport function SettingsPage(props: PluginSettingsPageProps) {\n const companyId = props.context.companyId ?? \"\";\n const themeMode = usePaperclipThemeMode();\n const { data, loading, error, refresh } = usePluginData<BotIdentitySettingsData>(\"bot-identity-config\", { companyId });\n const companyDisplayName = getCompanyDisplayName(data?.companyName, props.context.companyPrefix, companyId);\n const { data: agentsData, loading: agentsLoading, error: agentsError } = usePluginData<PaperclipAgentsData>(\"paperclip-agents\", { companyId });\n const saveConfig = usePluginAction(\"save-bot-identity-config\");\n const deleteConfig = usePluginAction(\"delete-bot-identity-config\");\n const createGitHubAppManifest = usePluginAction(\"create-github-app-manifest\");\n const getGitHubAppManifestFlow = usePluginAction(\"get-github-app-manifest-flow\");\n const convertGitHubAppManifest = usePluginAction(\"convert-github-app-manifest\");\n const createSlackAppManifest = usePluginAction(\"create-slack-app-manifest\");\n const getSlackAppManifestFlow = usePluginAction(\"get-slack-app-manifest-flow\");\n const discoverSlackInstallMetadata = usePluginAction(\"discover-slack-install-metadata\");\n const saveSlackInstallMetadata = usePluginAction(\"save-slack-install-metadata\");\n const rebindLegacySlackCredentials = usePluginAction(REBIND_LEGACY_SLACK_CREDENTIALS_ACTION);\n // Credential-free identity self-check tool (DRO-972) invoked the same way\n // as the plugin actions above. `usePluginAction` only calls\n // `ctx.actions.register` handlers, not `ctx.tools.register` handlers -- this\n // works because the worker also registers `uiActionInvocable` live tools as\n // actions under the same name (see the `uiInvocableLiveTools()` loop in\n // src/worker.ts), reusing the same pipeline handler. No separate hook is\n // needed from the client's perspective.\n const slackBotWhoami = usePluginAction(slackBotWhoamiToolName);\n\n const [formState, setFormState] = useState<IdentityFormState | null>(null);\n const [saving, setSaving] = useState(false);\n const [deletingAgentId, setDeletingAgentId] = useState<string | null>(null);\n const [saveError, setSaveError] = useState<string | null>(null);\n const [saveSuccess, setSaveSuccess] = useState(false);\n const [secretOptions, setSecretOptions] = useState<PaperclipSecretOption[]>([]);\n const [secretsLoading, setSecretsLoading] = useState(false);\n const [secretsError, setSecretsError] = useState<string | null>(null);\n const [activeFormSection, setActiveFormSection] = useState<IdentityFormSection>(\"identity\");\n const identities = data?.identities ?? [];\n const agentOptions = agentsData?.agents ?? [];\n const summary = summarizeIdentitySettings(identities);\n\n useEffect(() => {\n if (!companyId) {\n setSecretOptions([]);\n setSecretsError(null);\n setSecretsLoading(false);\n return;\n }\n\n let cancelled = false;\n setSecretsLoading(true);\n setSecretsError(null);\n void loadSecretOptions(companyId)\n .then((secrets) => {\n if (!cancelled) {\n setSecretOptions(secrets);\n }\n })\n .catch((err) => {\n if (!cancelled) {\n setSecretOptions([]);\n setSecretsError(err instanceof Error ? err.message : \"Could not load Paperclip secrets\");\n }\n })\n .finally(() => {\n if (!cancelled) {\n setSecretsLoading(false);\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [companyId]);\n\n const hasAgentOptions = agentOptions.length > 0;\n const config = formState;\n const persistedAgentId = config?.previousAgentId || config?.agentId;\n const isEditingExistingIdentity = Boolean(\n config && identities.some(\n (entry) => entry.agentId === persistedAgentId && entry.provider === config.provider,\n ),\n );\n\n // Slack's and GitHub's credential-step local state (manifest flow, busy\n // flags, errors, restore-on-mount effects, and the save/rebind handlers)\n // are each owned entirely by their provider's UI adapter -- see\n // src/providers/slack/settings-adapter-ui.tsx and\n // src/providers/github/settings-adapter-ui.tsx. SettingsPage only threads\n // in the shared inputs each hook needs (config, updateField, refresh,\n // deleteConfig, provider-specific plugin actions) and reads back\n // `validationExtra` (for getIdentityFormValidation) and `reset` (called\n // from startCreate/startEdit/agentId-or-label edits below).\n const slackUIState = providerSettingsUIRegistry.get(SLACK_IDENTITY_PROVIDER_ID)!.useCredentialStep({\n config: config as unknown as import(\"../providers/slack/settings-adapter-ui.js\").SlackSettingsUIFormConfig | null,\n hasPersistedIdentity: isEditingExistingIdentity,\n updateField: (field: string, value: string) => updateField(field as keyof IdentityFormState, value),\n refresh,\n deleteConfig,\n patchFormState: (patch: (prev: import(\"../providers/slack/settings-adapter-ui.js\").SlackSettingsUIFormConfig) => import(\"../providers/slack/settings-adapter-ui.js\").SlackSettingsUIFormConfig) => setFormState((prev) => (prev ? (patch(prev as unknown as import(\"../providers/slack/settings-adapter-ui.js\").SlackSettingsUIFormConfig) as unknown as IdentityFormState) : prev)),\n secretOptions,\n secretsLoading,\n secretsError,\n companyId,\n createSlackAppManifest,\n getSlackAppManifestFlow,\n discoverSlackInstallMetadata,\n saveSlackInstallMetadata,\n rebindLegacySlackCredentials,\n slackBotWhoami,\n });\n\n const githubUIState = providerSettingsUIRegistry.get(GITHUB_IDENTITY_PROVIDER_ID)!.useCredentialStep({\n config: config as unknown as import(\"../providers/github/settings-adapter-ui.js\").GitHubSettingsUIFormConfig | null,\n hasPersistedIdentity: isEditingExistingIdentity,\n updateField: (field: string, value: string) => updateField(field as keyof IdentityFormState, value),\n refresh,\n deleteConfig,\n // Unlike Slack's patchFormState (which only ever patches an already-open\n // dialog), the GitHub OAuth callback effect can fire with the dialog\n // closed (formState === null) -- the operator left the page entirely to\n // authorize the GitHub App and is now landing back on a fresh page load.\n // Falling back to a no-op there (as a plain `prev ? patch(prev) : prev`\n // would) silently drops the restored manifest flow and the wizard never\n // reopens. Construct a fresh base via `toFormState()` -- the same\n // construction `startCreate` uses to open the dialog -- so the patch\n // always has a form to apply to and the wizard reopens with the restored\n // state.\n patchFormState: (patch: (prev: import(\"../providers/github/settings-adapter-ui.js\").GitHubSettingsUIFormConfig) => import(\"../providers/github/settings-adapter-ui.js\").GitHubSettingsUIFormConfig) => setFormState((prev) => patch((prev ?? toFormState()) as unknown as import(\"../providers/github/settings-adapter-ui.js\").GitHubSettingsUIFormConfig) as unknown as IdentityFormState),\n secretOptions,\n secretsLoading,\n secretsError,\n companyId,\n createGitHubAppManifest,\n getGitHubAppManifestFlow,\n convertGitHubAppManifest,\n identities,\n agentOptions,\n companyDisplayName,\n credentialSidecarPath: data?.credentialSidecarPath ?? \"\",\n getAgentIdentityDefaults,\n toFormState,\n });\n\n // Provider-agnostic selection of the active provider's credential-step hook\n // state, component, and step id -- keyed off `config.provider` via the\n // registries rather than an `=== SLACK/GITHUB` branch in the render path\n // (findings #5/#10/#19). Both provider hooks must still be *called*\n // unconditionally above (Rules of Hooks), but only the active provider's\n // result is mounted.\n const activeProviderId = config?.provider ?? GITHUB_IDENTITY_PROVIDER_ID;\n // Known deferral (flagged repeatedly in review, e.g. against #63/#74): this\n // still branches on SLACK/GITHUB by name instead of having each hook result\n // carried through the registry itself, because `useCredentialStep` must be\n // called unconditionally for every provider (Rules of Hooks), and the\n // registry as typed today (`AnyProviderSettingsUIAdapter`, see\n // provider-settings-ui-contract.ts) has no place to stash the per-provider\n // hook *results* alongside the adapters. Fully registry-driven mounting\n // (no provider id branch at all) is left as follow-up scope, consistent\n // with the same deferral noted in provider-settings-contract.ts.\n const activeProviderUIState = activeProviderId === SLACK_IDENTITY_PROVIDER_ID ? slackUIState : githubUIState;\n const activeProviderUIAdapter = providerSettingsUIRegistry.get(activeProviderId);\n const ActiveCredentialStep = activeProviderUIAdapter?.CredentialStep;\n const activeProviderCredentialStepId = providerSettingsRegistry.get(activeProviderId).credentialStepId;\n\n const hasSavedAgentOutsideOptions = Boolean(\n config?.agentId && !agentOptions.some((agent) => agent.id === config.agentId)\n );\n const duplicateIdentity = config ? identities.find((entry) => entry.agentId === config.agentId && entry.provider === config.provider && !(config.previousAgentId === entry.agentId && config.provider === entry.provider)) : undefined;\n const formValidation = config\n ? getIdentityFormValidation(config, Boolean(duplicateIdentity), slackUIState.slackSaveResult, slackUIState.slackSaveBusy)\n : null;\n const activeFormSteps = getFormSteps(config?.provider ?? GITHUB_IDENTITY_PROVIDER_ID);\n const activeFormStepIndex = getFormStepIndex(activeFormSection, config?.provider ?? GITHUB_IDENTITY_PROVIDER_ID);\n const isLastFormStep = activeFormStepIndex === activeFormSteps.length - 1;\n const canGoNext = formValidation ? canAdvanceFromStep(activeFormSection, formValidation) : false;\n const canSave = Boolean(formValidation?.isComplete && isLastFormStep && !saving);\n // Finding #1: while save-slack-install-metadata is in flight, the worker\n // may already have persisted the new identity and consumed/deleted the\n // one-time manifest flow by the time the response comes back. Letting the\n // operator edit the Slack fields, switch the provider/agent, or navigate\n // away during that window can invalidate the client's view of what was\n // saved (see slackFieldsSignature invalidation in\n // useSlackCredentialStep) with no way to recover the flow. Lock the whole\n // identity-step fields and dialog navigation for the duration of the save.\n // Also lock during a pending cleanup-only retry (deleteConfig(previousAgentId)\n // re-attempt after save-slack-install-metadata succeeded): the operator\n // could otherwise click \"Retry cleanup\", then navigate/edit the identity\n // before it resolves, letting that stale response's state updates land on\n // a different form (Copilot finding on settings-adapter-ui.tsx:454).\n const slackSaveInFlight =\n activeProviderId === SLACK_IDENTITY_PROVIDER_ID && (\n slackUIState.slackSaveBusy\n || slackUIState.slackCleanupBusy\n || slackUIState.legacySlackRebindBusy\n );\n\n if (loading) return <div>Loading settings...</div>;\n if (error) return <div>Error loading settings: {error.message}</div>;\n\n function startCreate() {\n setActiveFormSection(\"identity\");\n setFormState(toFormState());\n setSaveError(null);\n setSaveSuccess(false);\n githubUIState.reset();\n slackUIState.reset();\n }\n\n function startEdit(entry: BotIdentitySettingsEntry) {\n setActiveFormSection(\"identity\");\n setFormState(toFormState(entry));\n setSaveError(null);\n setSaveSuccess(false);\n githubUIState.reset();\n slackUIState.reset();\n }\n\n function updateField(field: keyof IdentityFormState, value: string) {\n if (field === \"agentId\") {\n updateAgentSelection(value);\n } else {\n setFormState((prev) => ({\n ...(prev ?? toFormState()),\n [field]: value,\n }));\n }\n setSaveSuccess(false);\n setSaveError(null);\n if ((field === \"agentId\" || field === \"label\") && config?.[field] !== value) {\n githubUIState.reset();\n slackUIState.reset();\n }\n // Invalidating a prior save-slack-install-metadata result on a Slack\n // field edit (and clearing a now-stale slackSaveBusy) is handled inside\n // the Slack UI adapter's hook itself, which watches the relevant config\n // fields via a signature effect -- see useSlackCredentialStep in\n // src/providers/slack/settings-adapter-ui.tsx.\n }\n\n function updateAgentSelection(agentId: string) {\n setFormState((prev) => {\n const base = prev ?? toFormState();\n const selectedAgent = agentOptions.find((agent) => agent.id === agentId);\n if (!selectedAgent || base.previousAgentId || base.agentId === agentId) {\n return { ...base, agentId };\n }\n const defaults = getAgentIdentityDefaults(\n selectedAgent,\n companyDisplayName,\n data?.credentialSidecarPath ?? \"\",\n );\n return {\n ...base,\n agentId,\n label: shouldPrefillIdentityField(base.label, DEFAULT_BOT_IDENTITY_CONFIG.label) ? defaults.label : base.label,\n githubUsername: shouldPrefillIdentityField(base.githubUsername, DEFAULT_BOT_IDENTITY_CONFIG.github.username) ? defaults.githubUsername : base.githubUsername,\n commitName: shouldPrefillIdentityField(base.commitName, \"\") ? defaults.commitName : base.commitName,\n commitEmail: shouldPrefillIdentityField(base.commitEmail, \"\") ? defaults.commitEmail : base.commitEmail,\n privateKeyFile: shouldPrefillIdentityField(base.privateKeyFile, \"\") ? defaults.privateKeyFile : base.privateKeyFile,\n };\n });\n }\n\n async function handleSave() {\n if (!config) return;\n const validation = getIdentityFormValidation(config, Boolean(duplicateIdentity), slackUIState.slackSaveResult, slackUIState.slackSaveBusy);\n if (!validation.isComplete) {\n setSaveSuccess(false);\n setSaveError(validation.saveMessage);\n const adapter = providerSettingsRegistry.get(config.provider);\n setActiveFormSection(validation.identityComplete ? (adapter.credentialStepId as IdentityFormSection) : \"identity\");\n return;\n }\n if (providerSettingsRegistry.get(config.provider).savesViaSeparateAction) {\n // Slack identities are persisted by save-slack-install-metadata itself\n // (see handleSaveSlackInstallMetadata); there is no separate\n // save-bot-identity-config call for Slack. Reaching this step with a\n // complete validation means that action already ran successfully.\n setSaveSuccess(true);\n setFormState(null);\n return;\n }\n setSaving(true);\n setSaveError(null);\n setSaveSuccess(false);\n try {\n if (!isIdentityProviderId(config.provider)) {\n throw new Error(\"Choose a supported identity provider before saving.\");\n }\n const targetAgentId = config.agentId.trim();\n const previousAgentIds = config.previousAgentId && config.previousAgentId !== targetAgentId ? [config.previousAgentId] : [];\n const payload: SaveBotIdentityConfigInput = {\n agentId: config.agentId.trim(),\n previousAgentId: config.previousAgentId.trim() || undefined,\n provider: \"github\",\n label: config.label.trim(),\n github: {\n username: config.githubUsername.trim(),\n ...(config.commitName.trim() ? { commitName: config.commitName.trim() } : {}),\n ...(config.commitEmail.trim() ? { commitEmail: config.commitEmail.trim() } : {}),\n },\n credential: {\n secretId: config.fallbackTokenSecretId.trim() || undefined,\n tokenFile: config.tokenFile.trim() || undefined,\n githubApp: {\n appId: config.githubAppId.trim() || undefined,\n installationId: config.githubInstallationId.trim() || undefined,\n privateKeySecretId: config.privateKeySecretId.trim() || undefined,\n privateKeyFile: config.privateKeyFile.trim() || undefined,\n },\n },\n };\n const saved = await saveConfig(payload as unknown as Record<string, unknown>);\n await syncGitHubAppCredentialPropagationForAgents({\n selectedAgentIds: targetAgentId ? [targetAgentId] : [],\n previousAgentIds,\n githubAppId: config.githubAppId.trim() || undefined,\n githubInstallationId: config.githubInstallationId.trim() || undefined,\n privateKeySecretRef: config.privateKeySecretId.trim() || undefined,\n privateKeyFile: config.privateKeyFile.trim() || undefined,\n previousGithubAppId: config.previousGithubAppId || undefined,\n previousGithubInstallationId: config.previousGithubInstallationId || undefined,\n previousPrivateKeySecretRef: config.previousPrivateKeySecretId || undefined,\n previousPrivateKeyFile: config.previousPrivateKeyFile || undefined,\n });\n setSaveSuccess(true);\n await refresh();\n const savedEntry = (saved as BotIdentitySettingsEntry | undefined)?.agentId ? saved as BotIdentitySettingsEntry : null;\n setFormState(savedEntry ? toFormState(savedEntry) : null);\n } catch (err) {\n setSaveError(err instanceof Error ? err.message : \"Failed to save\");\n } finally {\n setSaving(false);\n }\n }\n\n async function handleDelete(entry: BotIdentitySettingsEntry) {\n // Per-provider recovery-guidance copy is composed through the UI\n // registry's optional getRemovalConfirmation (see\n // provider-settings-ui-contract.ts) rather than a `provider === \"slack\"`\n // branch here; providers that don't implement it fall back to this\n // generic message.\n const confirmationMessage =\n providerSettingsUIRegistry.get(entry.provider)?.getRemovalConfirmation?.(entry) ??\n `Delete agent identity mapping for ${entry.label}?`;\n const confirmed = window.confirm(confirmationMessage);\n if (!confirmed) return;\n setDeletingAgentId(entry.agentId);\n setSaveError(null);\n setSaveSuccess(false);\n try {\n await deleteConfig({ agentId: entry.agentId, provider: entry.provider });\n if (formState?.agentId === entry.agentId && formState.provider === entry.provider) {\n setFormState(null);\n }\n await refresh();\n\n if (hasGitHubAppPropagationValues(entry)) {\n try {\n await syncGitHubAppCredentialPropagationForAgents({\n selectedAgentIds: [],\n previousAgentIds: [entry.agentId],\n previousGithubAppId: entry.credential?.githubApp?.appId,\n previousGithubInstallationId: entry.credential?.githubApp?.installationId,\n previousPrivateKeySecretRef: entry.credential?.githubApp?.privateKeySecretId,\n previousPrivateKeyFile: entry.credential?.githubApp?.privateKeyFile,\n });\n } catch (err) {\n setSaveError(`Deleted identity, but could not clean the agent environment: ${err instanceof Error ? err.message : \"unknown error\"}`);\n }\n }\n } catch (err) {\n setSaveError(err instanceof Error ? err.message : \"Failed to delete\");\n } finally {\n setDeletingAgentId(null);\n }\n }\n\n return (\n <div\n className=\"agent-identities-settings\"\n style={{ ...createPaperclipThemeStyle(themeMode), ...pageStyle }}\n data-agent-identities-theme={themeMode}\n >\n <style>{responsiveSettingsStyle}</style>\n <div className=\"agent-identities-header\" style={headerStyle}>\n <div>\n <h2 style={pageTitleStyle}>Agent Identities</h2>\n <p style={descriptionStyle}>\n Connect agents in {companyDisplayName || \"this company\"} to GitHub and Slack identities.\n </p>\n </div>\n </div>\n\n <div className=\"agent-identities-summary-grid\" style={summaryGridStyle}>\n <SummaryTile label=\"Identities\" value={summary.total} />\n <SummaryTile label=\"Ready\" value={summary.ready} tone=\"good\" />\n <SummaryTile label=\"Need setup\" value={summary.needsSetup} tone={summary.needsSetup > 0 ? \"warn\" : \"good\"} />\n </div>\n\n {data?.credentialSidecarError && (\n <div style={credentialErrorStyle}>\n Credential source unavailable: {data.credentialSidecarError}\n </div>\n )}\n\n <section style={sectionStyle}>\n <div className=\"agent-identities-section-header\" style={sectionHeaderStyle}>\n <div>\n <h3 style={sectionTitleStyle}>Configured identities</h3>\n <p style={sectionDescriptionStyle}>Each row maps one Paperclip agent to a provider account and credential source.</p>\n </div>\n <button onClick={startCreate} style={secondaryButtonStyle}>Add identity</button>\n </div>\n {saveError && !formState && <div style={errorStyle}>{saveError}</div>}\n {saveSuccess && !formState && <div style={successStyle}>Saved successfully.</div>}\n {identities.length === 0 ? (\n <div style={emptyStateStyle}>\n <strong>No identities configured</strong>\n <span>Pick an agent, connect its first provider account, then save. Defaults are filled from the selected agent and company.</span>\n <button onClick={startCreate} style={primaryButtonStyle}>Create first identity</button>\n </div>\n ) : (\n <div style={listStyle}>\n <div className=\"agent-identities-list-header\" style={listHeaderStyle}>\n <span>Agent</span>\n <span>Provider</span>\n <span>Status</span>\n <span />\n </div>\n {identities.map((entry) => (\n <div key={entry.id} className=\"agent-identities-list-row\" style={rowStyle}>\n <div style={{ minWidth: 0 }}>\n <div style={rowTitleStyle}>{entry.label}</div>\n <div style={rowMetaStyle}>{formatAgentName(entry.agentId, agentOptions)}</div>\n </div>\n <div style={rowMetaStyle}>{getProviderDisplayName(entry.provider, data?.providers)}</div>\n <span style={statusBadgeStyle(getIdentityTone(entry))}>{formatCredentialStatus(entry.credentialStatus)}</span>\n <div className=\"agent-identities-row-actions\" style={rowActionsStyle}>\n <button onClick={() => startEdit(entry)} style={secondaryButtonStyle}>Edit</button>\n <button\n onClick={() => void handleDelete(entry)}\n disabled={deletingAgentId === entry.agentId}\n style={dangerButtonStyle}\n >\n {deletingAgentId === entry.agentId ? \"Deleting...\" : \"Delete\"}\n </button>\n </div>\n </div>\n ))}\n </div>\n )}\n </section>\n\n {config && (\n <div style={dialogBackdropStyle} role=\"presentation\">\n <section\n className=\"agent-identities-dialog\"\n style={dialogStyle}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"agent-identity-dialog-title\"\n >\n <header className=\"agent-identities-dialog-header\" style={dialogHeaderStyle}>\n <div>\n <h3 id=\"agent-identity-dialog-title\" style={dialogTitleStyle}>{isEditingExistingIdentity ? \"Edit agent identity\" : \"Add agent identity\"}</h3>\n <p style={sectionDescriptionStyle}>Configure the agent and its provider-specific credentials.</p>\n </div>\n <button onClick={() => setFormState(null)} disabled={saving || slackSaveInFlight} style={closeButtonStyle} aria-label=\"Close identity editor\">x</button>\n </header>\n\n <div style={dialogBodyStyle}>\n <div className=\"agent-identities-wizard-steps\" aria-label=\"Identity setup progress\" style={wizardStepListStyle}>\n {activeFormSteps.map((step, index) => (\n <WizardStepIndicator\n key={step.id}\n index={index + 1}\n label={step.label}\n active={step.id === activeFormSection}\n complete={formValidation ? isWizardStepComplete(step.id, formValidation) : false}\n />\n ))}\n </div>\n\n {activeFormSection === \"identity\" && (\n <>\n <fieldset style={fieldsetStyle}>\n <legend style={legendStyle}>Identity</legend>\n {formValidation && !formValidation.identityComplete && <div style={validationNoticeStyle}>{formValidation.identityMessage}</div>}\n\n <label style={fieldStyle}>\n <span>Agent <span style={requiredStyle}>*</span></span>\n {hasAgentOptions ? (\n <select\n value={config.agentId}\n onChange={(e) => updateField(\"agentId\", e.target.value)}\n style={inputStyle}\n disabled={slackSaveInFlight}\n >\n <option value=\"\" disabled>Select a Paperclip agent</option>\n {hasSavedAgentOutsideOptions && <option value={config.agentId}>{config.agentId} (saved)</option>}\n {agentOptions.map((agent) => (\n <option key={agent.id} value={agent.id}>{formatAgentOption(agent)}</option>\n ))}\n </select>\n ) : (\n <input\n type=\"text\"\n value={config.agentId}\n onChange={(e) => updateField(\"agentId\", e.target.value)}\n placeholder=\"UUID of the Paperclip agent\"\n style={inputStyle}\n disabled={slackSaveInFlight}\n />\n )}\n <span style={hintStyle}>{getAgentFieldHint({ companyId, agentsLoading, agentsError, hasAgentOptions })}</span>\n </label>\n\n <label style={fieldStyle}>\n <span>Provider <span style={requiredStyle}>*</span></span>\n <select value={config.provider} onChange={(e) => updateField(\"provider\", e.target.value)} style={inputStyle} disabled={isEditingExistingIdentity || slackSaveInFlight}>\n {(data?.providers ?? []).map((provider) => (\n <option\n key={provider.id}\n value={provider.id}\n disabled={provider.status !== \"enabled\" && provider.id !== SLACK_IDENTITY_PROVIDER_ID}\n >\n {provider.name}{provider.status === \"coming-soon\" ? (provider.id === SLACK_IDENTITY_PROVIDER_ID ? \"\" : \" (coming soon)\") : \"\"}\n </option>\n ))}\n </select>\n <span style={hintStyle}>Each agent can have one identity per provider. GitHub and Slack are available, with additional providers coming soon.</span>\n </label>\n\n {duplicateIdentity && <div style={validationNoticeStyle}>This agent already has a {getProviderDisplayName(config.provider, data?.providers)} identity. Edit the existing row instead.</div>}\n\n <label style={fieldStyle}>\n <span>Label <span style={requiredStyle}>*</span></span>\n <input\n type=\"text\"\n value={config.label}\n onChange={(e) => updateField(\"label\", e.target.value)}\n placeholder=\"e.g. Cade Riven [Droidshop]\"\n style={inputStyle}\n disabled={slackSaveInFlight}\n />\n </label>\n </fieldset>\n\n {providerSettingsRegistry.get(config.provider).hasProviderAccountFieldsInIdentityStep && (\n <fieldset style={fieldsetStyle}>\n <legend style={legendStyle}>Provider account</legend>\n\n <label style={fieldStyle}>\n <span>GitHub Username <span style={requiredStyle}>*</span></span>\n <input\n type=\"text\"\n value={config.githubUsername}\n onChange={(e) => updateField(\"githubUsername\", e.target.value)}\n placeholder=\"e.g. ouroboros-paperclip-agent[bot]\"\n style={inputStyle}\n />\n <span style={hintStyle}>Public GitHub App login for this agent. GitHub appends [bot] to app account logins. Repository access is controlled by the GitHub App installation and provider permissions.</span>\n </label>\n </fieldset>\n )}\n </>\n )}\n\n {/* The active provider's credential step is mounted entirely from\n the UI registry -- the shared page no longer branches on provider\n id strings here (findings #5/#10/#19). The current provider's\n adapter decides which step id holds its credential fieldset\n (`credentialStepId`), and we thread in that same provider's hook\n state (already selected as `activeProviderUIState` above). */}\n {activeFormSection === activeProviderCredentialStepId && ActiveCredentialStep && (\n <ActiveCredentialStep\n state={activeProviderUIState}\n config={config as unknown as Record<string, string>}\n />\n )}\n {activeFormSection === \"commit\" && (\n <fieldset style={fieldsetStyle}>\n <legend style={legendStyle}>Commit identity (optional)</legend>\n <div style={inlineNoticeStyle}>These fields are optional. Save is available because the required identity and credential steps are complete.</div>\n\n <label style={fieldStyle}>\n <span>Commit Name</span>\n <input\n type=\"text\"\n value={config.commitName}\n onChange={(e) => updateField(\"commitName\", e.target.value)}\n placeholder=\"e.g. Ouroboros Paperclip Agent\"\n style={inputStyle}\n />\n </label>\n\n <label style={fieldStyle}>\n <span>Commit Email</span>\n <input\n type=\"text\"\n value={config.commitEmail}\n onChange={(e) => updateField(\"commitEmail\", e.target.value)}\n placeholder=\"e.g. agent@example.com\"\n style={inputStyle}\n />\n </label>\n </fieldset>\n )}\n\n </div>\n\n <footer className=\"agent-identities-dialog-footer\" style={dialogFooterStyle}>\n <div style={saveStatusStyle}>\n {saveSuccess && <span style={successStyle}>Saved successfully.</span>}\n {saveError && <span style={errorStyle}>{saveError}</span>}\n {!saveSuccess && !saveError && formValidation && !isLastFormStep && <span style={hintStyle}>{formValidation.saveMessage}</span>}\n {!saveSuccess && !saveError && formValidation && isLastFormStep && !formValidation.isComplete && <span style={hintStyle}>{formValidation.saveMessage}</span>}\n </div>\n <button\n type=\"button\"\n onClick={() => setActiveFormSection(getPreviousFormStep(activeFormSection, config.provider))}\n disabled={saving || slackSaveInFlight || activeFormStepIndex === 0}\n style={buttonStyle(secondaryButtonStyle, saving || slackSaveInFlight || activeFormStepIndex === 0)}\n >\n Previous\n </button>\n {!isLastFormStep ? (\n <button\n type=\"button\"\n onClick={() => setActiveFormSection(getNextFormStep(activeFormSection, config.provider))}\n disabled={saving || slackSaveInFlight || !canGoNext}\n style={buttonStyle(primaryButtonStyle, saving || slackSaveInFlight || !canGoNext)}\n >\n Next\n </button>\n ) : (\n <button\n type=\"button\"\n onClick={() => void handleSave()}\n disabled={!canSave}\n style={buttonStyle(primaryButtonStyle, !canSave)}\n >\n {saving ? \"Saving...\" : \"Save agent\"}\n </button>\n )}\n <button type=\"button\" onClick={() => setFormState(null)} disabled={saving || slackSaveInFlight} style={secondaryButtonStyle}>Cancel</button>\n </footer>\n </section>\n </div>\n )}\n </div>\n );\n}\n\n\nfunction SummaryTile(props: { label: string; value: number; tone?: IdentityTone }) {\n return (\n <div style={summaryTileStyle(props.tone ?? \"neutral\")}>\n <span style={summaryValueStyle}>{props.value}</span>\n <span style={summaryLabelStyle}>{props.label}</span>\n </div>\n );\n}\n\nfunction WizardStepIndicator(props: { index: number; label: string; active: boolean; complete: boolean }) {\n return (\n <div style={wizardStepStyle(props.active)}>\n <span style={wizardStepNumberStyle(props.active, props.complete)}>{props.complete ? \"\u2713\" : props.index}</span>\n <span>{props.label}</span>\n </div>\n );\n}\n\nfunction getAgentIdentityDefaults(\n agent: PaperclipAgentOption,\n companyDisplayName: string,\n credentialSidecarPath: string,\n): Pick<IdentityFormState, \"label\" | \"githubUsername\" | \"commitName\" | \"commitEmail\" | \"privateKeyFile\"> {\n const displayName = getAgentDisplayName(agent);\n const slug = slugifyGitHubAppName(displayName);\n return {\n label: formatIdentityLabel(displayName, companyDisplayName),\n githubUsername: `${slug}[bot]`,\n commitName: `${displayName} Paperclip Agent`,\n commitEmail: `${slug}[bot]@users.noreply.github.com`,\n privateKeyFile: getGitHubAppPrivateKeyFile(credentialSidecarPath, agent.id),\n };\n}\n\nexport function getGitHubAppPrivateKeyFile(credentialSidecarPath: string, agentId: string): string {\n const lastSeparator = Math.max(\n credentialSidecarPath.lastIndexOf(\"/\"),\n credentialSidecarPath.lastIndexOf(\"\\\\\"),\n );\n if (lastSeparator < 0) return \"\";\n const separator = credentialSidecarPath[lastSeparator];\n const directory = credentialSidecarPath.slice(0, lastSeparator);\n return `${directory}${separator}github-apps${separator}${agentId}${separator}private-key.pem`;\n}\n\nfunction shouldPrefillIdentityField(value: string, defaultValue: string): boolean {\n return value.trim() === defaultValue.trim();\n}\n\nfunction formatIdentityLabel(agentName: string, companyDisplayName: string): string {\n const companySuffix = companyDisplayName.trim();\n return companySuffix ? agentName + \" [\" + companySuffix + \"]\" : agentName;\n}\n\nfunction getAgentDisplayName(agent: PaperclipAgentOption): string {\n return (agent.name || agent.title || agent.role || agent.id).trim();\n}\n\nfunction getCompanyDisplayName(companyName: string | null | undefined, companyPrefix: string | null | undefined, companyId: string): string {\n const resolvedName = (companyName ?? \"\").trim();\n if (resolvedName) return resolvedName;\n\n const displayName = titleCaseSlug(companyPrefix ?? \"\");\n return displayName || companyId.trim();\n}\n\nfunction titleCaseSlug(value: string): string {\n return value\n .trim()\n .replace(/[ _-]+/g, \" \")\n .replace(/\\s+/g, \" \")\n .replace(/\\b\\w/g, (match) => match.toUpperCase());\n}\n\nfunction slugifyGitHubAppName(value: string): string {\n return value\n .normalize(\"NFKD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\") || \"paperclip-agent\";\n}\n\nexport function toFormState(entry?: BotIdentitySettingsEntry): IdentityFormState {\n return {\n agentId: entry?.agentId ?? DEFAULT_BOT_IDENTITY_CONFIG.agentId,\n provider: entry?.provider ?? DEFAULT_BOT_IDENTITY_CONFIG.provider,\n label: entry?.label ?? DEFAULT_BOT_IDENTITY_CONFIG.label,\n githubUsername: entry?.provider === \"github\" ? entry.github.username : DEFAULT_BOT_IDENTITY_CONFIG.github.username,\n commitName: entry?.provider === \"github\" ? entry.github.commitName ?? \"\" : \"\",\n commitEmail: entry?.provider === \"github\" ? entry.github.commitEmail ?? \"\" : \"\",\n githubAppId: entry?.credential?.githubApp?.appId ?? \"\",\n githubInstallationId: entry?.credential?.githubApp?.installationId ?? \"\",\n privateKeySecretId: entry?.credential?.githubApp?.privateKeySecretId ?? \"\",\n privateKeyFile: entry?.credential?.githubApp?.privateKeyFile ?? \"\",\n fallbackTokenSecretId: entry?.credential?.secretId ?? \"\",\n tokenFile: entry?.credential?.tokenFile ?? \"\",\n previousAgentId: entry?.agentId ?? \"\",\n previousGithubAppId: entry?.credential?.githubApp?.appId ?? \"\",\n previousGithubInstallationId: entry?.credential?.githubApp?.installationId ?? \"\",\n previousPrivateKeySecretId: entry?.credential?.githubApp?.privateKeySecretId ?? \"\",\n previousPrivateKeyFile: entry?.credential?.githubApp?.privateKeyFile ?? \"\",\n slackTeamId: entry?.provider === \"slack\" ? entry.slack.teamId : \"\",\n slackAppId: entry?.provider === \"slack\" ? entry.slack.appId : \"\",\n slackBotUserId: entry?.provider === \"slack\" ? entry.slack.botUserId : \"\",\n slackDefaultChannel: entry?.provider === \"slack\" ? entry.slack.defaultChannel ?? \"\" : \"\",\n slackEventsRequestUrl: entry?.provider === \"slack\" ? entry.slackSetup?.eventsRequestUrl ?? \"\" : \"\",\n slackBotTokenSecretId: entry?.provider === \"slack\" ? entry.slackSetup?.botTokenSecretId ?? \"\" : \"\",\n slackSigningSecretId: entry?.provider === \"slack\" ? entry.slackSetup?.signingSecretId ?? \"\" : \"\",\n slackLegacyCredentialStatus: entry?.provider === \"slack\"\n ? entry.slackSetup?.legacyCredential?.status ?? \"\"\n : \"\",\n slackLegacySigningSecretRequired: entry?.provider === \"slack\" && entry.slackSetup?.legacyCredential?.signingSecretRequired\n ? \"true\"\n : \"\",\n };\n}\n\n// Composed once here from the per-provider Settings-UI adapters\n// (src/providers/*/settings-adapter.ts) via src/providers/settings-index.ts,\n// mirroring how src/providers/index.ts composes ALL_PROVIDERS for the\n// worker/manifest tool surface -- kept as a separate composition root because\n// providers/index.ts pulls in server-only code unsafe for this client bundle\n// (see settings-index.ts). SettingsPage no longer branches on provider id\n// strings to pick a step list or validation rule set -- it looks up the\n// adapter for the active provider and delegates.\nconst providerSettingsRegistry = buildProviderSettingsRegistry([...ALL_SETTINGS_ADAPTERS], GITHUB_IDENTITY_PROVIDER_ID);\n\nexport function getFormSteps(provider: string): Array<{ id: IdentityFormSection; label: string }> {\n return providerSettingsRegistry.get(provider).formSteps as Array<{ id: IdentityFormSection; label: string }>;\n}\n\nexport function getIdentityFormValidation(\n config: IdentityFormState,\n hasDuplicate = false,\n slackSaveResult: SaveSlackInstallMetadataResult | null = null,\n slackSaveBusy = false,\n): IdentityFormValidation {\n const adapter = providerSettingsRegistry.get(config.provider);\n return adapter.getValidation(config, hasDuplicate, { slackSaveResult, slackSaveBusy });\n}\n\nfunction getFormStepIndex(step: IdentityFormSection, provider: string): number {\n return getFormSteps(provider).findIndex((entry) => entry.id === step);\n}\n\nfunction getNextFormStep(step: IdentityFormSection, provider: string): IdentityFormSection {\n const steps = getFormSteps(provider);\n return steps[Math.min(getFormStepIndex(step, provider) + 1, steps.length - 1)]?.id ?? step;\n}\n\nfunction getPreviousFormStep(step: IdentityFormSection, provider: string): IdentityFormSection {\n const steps = getFormSteps(provider);\n return steps[Math.max(getFormStepIndex(step, provider) - 1, 0)]?.id ?? step;\n}\n\nfunction canAdvanceFromStep(step: IdentityFormSection, validation: IdentityFormValidation): boolean {\n if (step === \"identity\") return validation.identityComplete;\n if (step === \"github\" || step === \"slack\") return validation.credentialComplete;\n return validation.isComplete;\n}\n\nfunction isWizardStepComplete(step: IdentityFormSection, validation: IdentityFormValidation): boolean {\n if (step === \"identity\") return validation.identityComplete;\n if (step === \"github\" || step === \"slack\") return validation.credentialComplete;\n return validation.isComplete;\n}\n\nfunction formatAgentOption(agent: PaperclipAgentOption): string {\n const details = [agent.role, agent.status].filter(Boolean).join(\" - \");\n return details ? `${getAgentDisplayName(agent)} (${details})` : getAgentDisplayName(agent);\n}\n\nfunction formatAgentName(agentId: string, agents: PaperclipAgentOption[]): string {\n const agent = agents.find((entry) => entry.id === agentId);\n return agent ? getAgentDisplayName(agent) : agentId;\n}\n\nfunction getProviderDisplayName(providerId: string, providers: BotIdentitySettingsData[\"providers\"] | undefined): string {\n return providers?.find((provider) => provider.id === providerId)?.name ?? providerId;\n}\n\nexport function formatSecretOption(secret: PaperclipSecretOption): string {\n const label = secret.name || secret.key || secret.id;\n const details = [secret.key && secret.key !== label ? secret.key : null, secret.status, secret.provider]\n .filter(Boolean)\n .join(\" - \");\n return details ? `${label} (${details})` : label;\n}\n\nexport function getSecretFieldHint(input: {\n companyId: string;\n secretsLoading: boolean;\n secretsError: string | null;\n hasSecretOptions: boolean;\n}): string {\n if (!input.companyId) {\n return \"No company context is available, so paste the Paperclip secret UUID manually.\";\n }\n if (input.secretsLoading) {\n return \"Loading Paperclip secrets...\";\n }\n if (input.secretsError) {\n return `Could not load Paperclip secrets (${input.secretsError}); paste the secret UUID manually.`;\n }\n if (!input.hasSecretOptions) {\n return \"No Paperclip secrets were found; paste the private key secret UUID manually or use a private key file fallback.\";\n }\n return \"Saved as a Paperclip secret reference for the GitHub App private key and optionally propagated to agent environments.\";\n}\n\nexport function getFallbackTokenSecretFieldHint(input: {\n companyId: string;\n secretsLoading: boolean;\n secretsError: string | null;\n hasSecretOptions: boolean;\n}): string {\n if (!input.companyId) {\n return \"No company context is available, so paste the fallback token secret UUID manually.\";\n }\n if (input.secretsLoading) {\n return \"Loading Paperclip secrets...\";\n }\n if (input.secretsError) {\n return `Could not load Paperclip secrets (${input.secretsError}); paste the fallback token secret UUID manually.`;\n }\n if (!input.hasSecretOptions) {\n return \"No Paperclip secrets were found; paste the fallback token secret UUID manually or use a fallback token file.\";\n }\n return \"Optional fallback token secret. Prefer GitHub App credentials above.\";\n}\n\n\nasync function loadSecretOptions(companyId: string): Promise<PaperclipSecretOption[]> {\n const encodedCompanyId = encodeURIComponent(companyId);\n const paths = [\n `/api/companies/${encodedCompanyId}/secrets`,\n `/api/companies/${encodedCompanyId}/me/user-secrets`,\n ];\n\n let lastError: Error | null = null;\n for (const path of paths) {\n try {\n const response = await fetch(path, {\n credentials: \"include\",\n headers: { accept: \"application/json\" },\n });\n if (!response.ok) {\n lastError = new Error(`${response.status} ${response.statusText}`.trim());\n continue;\n }\n return normalizeSecretOptions(await response.json());\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err));\n }\n }\n\n throw lastError ?? new Error(\"Paperclip secrets API unavailable\");\n}\n\nfunction normalizeSecretOptions(raw: unknown): PaperclipSecretOption[] {\n const candidates = Array.isArray(raw)\n ? raw\n : isRecord(raw) && Array.isArray(raw.secrets)\n ? raw.secrets\n : isRecord(raw) && Array.isArray(raw.userSecrets)\n ? raw.userSecrets\n : isRecord(raw) && Array.isArray(raw.companySecrets)\n ? raw.companySecrets\n : isRecord(raw) && Array.isArray(raw.items)\n ? raw.items\n : isRecord(raw) && Array.isArray(raw.results)\n ? raw.results\n : isRecord(raw) && Array.isArray(raw.data)\n ? raw.data\n : [];\n\n return candidates\n .map((entry) => normalizeSecretOption(entry))\n .filter((entry): entry is PaperclipSecretOption => Boolean(entry))\n .filter((entry) => !entry.status || entry.status === \"active\")\n .sort((left, right) => (left.name || left.key || left.id).localeCompare(right.name || right.key || right.id));\n}\n\nfunction normalizeSecretOption(raw: unknown): PaperclipSecretOption | null {\n const entry = isRecord(raw) && isRecord(raw.secret) ? raw.secret : raw;\n if (!isRecord(entry)) return null;\n const id = readString(entry.id) || readString(entry.secretId);\n if (!id) return null;\n\n return {\n id,\n name: readString(entry.name) || readString(entry.label) || readString(entry.key) || id,\n key: readString(entry.key) || undefined,\n description: readString(entry.description) || undefined,\n provider: readString(entry.provider) || undefined,\n status: readString(entry.status) || undefined,\n };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction readString(value: unknown): string {\n return typeof value === \"string\" ? value.trim() : \"\";\n}\n\nfunction formatCredentialStatus(status: BotIdentitySettingsEntry[\"credentialStatus\"]): string {\n if (status === \"configured\") return \"Configured\";\n if (status === \"rebind-required\") return \"Rebind required\";\n if (status === \"cleanup-pending\") return \"Cleanup pending\";\n if (status === \"conflict\") return \"Conflict\";\n if (status === \"sidecar-unavailable\") return \"Unavailable\";\n return \"Missing\";\n}\n\nfunction getIdentityTone(entry: BotIdentitySettingsEntry): IdentityTone {\n if (entry.credentialStatus === \"configured\") return \"good\";\n if (entry.credentialStatus !== \"missing\") return \"warn\";\n return \"neutral\";\n}\n\nfunction summarizeIdentitySettings(identities: BotIdentitySettingsEntry[]) {\n const ready = identities.filter((identity) => identity.credentialStatus === \"configured\").length;\n return {\n total: identities.length,\n ready,\n needsSetup: identities.filter((identity) => identity.credentialStatus !== \"configured\").length,\n };\n}\n\nfunction hasGitHubAppPropagationValues(entry: BotIdentitySettingsEntry): boolean {\n const githubApp = entry.credential?.githubApp;\n return Boolean(githubApp?.appId && githubApp.installationId && (githubApp.privateKeySecretId || githubApp.privateKeyFile));\n}\n\ntype AgentAdapterConfig = Record<string, unknown> & { env?: Record<string, unknown> };\n\ntype AgentPropagationMode = \"ensure\" | \"remove\";\n\ntype GitHubAppPropagationConfig = {\n appId: string;\n installationId: string;\n privateKeySecretRef?: string;\n privateKeyFile?: string;\n};\n\ntype AgentPropagationPatchInput = {\n adapterConfig: unknown;\n githubApp: GitHubAppPropagationConfig;\n mode: AgentPropagationMode;\n};\n\nconst GITHUB_APP_PROPAGATION_CONCURRENCY_LIMIT = 4;\n\nasync function syncGitHubAppCredentialPropagationForAgents(input: {\n selectedAgentIds: string[];\n previousAgentIds: string[];\n githubAppId?: string;\n githubInstallationId?: string;\n privateKeySecretRef?: string;\n privateKeyFile?: string;\n previousGithubAppId?: string;\n previousGithubInstallationId?: string;\n previousPrivateKeySecretRef?: string;\n previousPrivateKeyFile?: string;\n}): Promise<void> {\n const selectedAgentIds = normalizeAgentIds(input.selectedAgentIds);\n const previousAgentIds = normalizeAgentIds(input.previousAgentIds);\n const selectedAgentIdSet = new Set(selectedAgentIds);\n const removeAgentIds = previousAgentIds.filter((agentId) => !selectedAgentIdSet.has(agentId));\n const operations: Array<{ agentId: string; mode: AgentPropagationMode; githubApp: GitHubAppPropagationConfig }> = [];\n\n if (selectedAgentIds.length > 0) {\n const selectedConfig = {\n appId: input.githubAppId,\n installationId: input.githubInstallationId,\n privateKeySecretRef: input.privateKeySecretRef,\n privateKeyFile: input.privateKeyFile,\n };\n if (hasCompleteGitHubAppValues(selectedConfig)) {\n const githubApp = buildGitHubAppPropagationConfig(selectedConfig);\n operations.push(...selectedAgentIds.map((agentId) => ({ agentId, mode: \"ensure\" as const, githubApp })));\n }\n }\n\n if (removeAgentIds.length > 0) {\n const removeConfig = {\n appId: input.previousGithubAppId ?? input.githubAppId,\n installationId: input.previousGithubInstallationId ?? input.githubInstallationId,\n privateKeySecretRef: input.previousPrivateKeySecretRef ?? input.privateKeySecretRef,\n privateKeyFile: input.previousPrivateKeyFile ?? input.privateKeyFile,\n };\n if (hasCompleteGitHubAppValues(removeConfig)) {\n const githubApp = buildGitHubAppPropagationConfig(removeConfig);\n operations.push(...removeAgentIds.map((agentId) => ({ agentId, mode: \"remove\" as const, githubApp })));\n }\n }\n\n const failures = new Set<string>();\n await runWithConcurrencyLimit(operations, GITHUB_APP_PROPAGATION_CONCURRENCY_LIMIT, async (operation) => {\n try {\n await applyGitHubAppPropagationUpdate(operation);\n } catch {\n failures.add(operation.agentId);\n }\n });\n\n if (failures.size > 0) {\n throw new Error(`GitHub App credential propagation could not update these agents: ${[...failures].join(\", \")}.`);\n }\n}\n\nfunction hasCompleteGitHubAppValues(input: { appId?: string; installationId?: string; privateKeySecretRef?: string; privateKeyFile?: string }): boolean {\n const appId = input.appId?.trim();\n const installationId = input.installationId?.trim();\n const privateKeySecretRef = input.privateKeySecretRef?.trim();\n const privateKeyFile = input.privateKeyFile?.trim();\n return Boolean(appId && installationId && (privateKeySecretRef || privateKeyFile));\n}\n\nfunction buildGitHubAppPropagationConfig(\n input: {\n appId?: string;\n installationId?: string;\n privateKeySecretRef?: string;\n privateKeyFile?: string;\n }\n): GitHubAppPropagationConfig {\n const appId = input.appId?.trim();\n const installationId = input.installationId?.trim();\n const privateKeySecretRef = input.privateKeySecretRef?.trim();\n const privateKeyFile = input.privateKeyFile?.trim();\n if (!appId || !installationId || (!privateKeySecretRef && !privateKeyFile)) {\n throw new Error(\"GitHub App credential propagation requires app ID, installation ID, and a private key secret or file.\");\n }\n return {\n appId,\n installationId,\n ...(privateKeySecretRef ? { privateKeySecretRef } : {}),\n ...(privateKeyFile ? { privateKeyFile } : {}),\n };\n}\n\nfunction normalizeAgentIds(value: string[]): string[] {\n return value\n .map((entry) => entry.trim())\n .filter(Boolean)\n .filter((entry, index, entries) => entries.indexOf(entry) === index);\n}\n\nasync function runWithConcurrencyLimit<T>(\n items: T[],\n concurrencyLimit: number,\n worker: (item: T) => Promise<void>\n): Promise<void> {\n if (items.length === 0) return;\n let nextIndex = 0;\n const runnerCount = Math.min(concurrencyLimit, items.length);\n await Promise.all(Array.from({ length: runnerCount }, async () => {\n while (nextIndex < items.length) {\n const currentIndex = nextIndex;\n nextIndex += 1;\n await worker(items[currentIndex]);\n }\n }));\n}\n\nasync function applyGitHubAppPropagationUpdate(input: {\n agentId: string;\n mode: AgentPropagationMode;\n githubApp: GitHubAppPropagationConfig;\n}): Promise<void> {\n const agent = await fetchJson(`/api/agents/${encodeURIComponent(input.agentId)}`);\n const nextAdapterConfig = getAgentPropagationPatch({\n adapterConfig: isRecord(agent) ? agent.adapterConfig : undefined,\n githubApp: input.githubApp,\n mode: input.mode,\n });\n\n if (!nextAdapterConfig) {\n return;\n }\n\n await fetchJson(`/api/agents/${encodeURIComponent(input.agentId)}`, {\n method: \"PATCH\",\n body: JSON.stringify({\n adapterConfig: nextAdapterConfig,\n replaceAdapterConfig: true,\n }),\n });\n}\n\nfunction getAgentPropagationPatch(input: AgentPropagationPatchInput): AgentAdapterConfig | null {\n const adapterConfig = isRecord(input.adapterConfig) ? { ...input.adapterConfig } as AgentAdapterConfig : {};\n const currentEnv = isRecord(adapterConfig.env) ? { ...adapterConfig.env } : {};\n\n if (input.mode === \"ensure\") {\n const nextEnv: Record<string, unknown> = {\n ...currentEnv,\n GITHUB_APP_ID: input.githubApp.appId,\n GITHUB_INSTALLATION_ID: input.githubApp.installationId,\n };\n if (input.githubApp.privateKeySecretRef) {\n nextEnv.GITHUB_APP_PRIVATE_KEY = {\n type: \"secret_ref\",\n secretId: input.githubApp.privateKeySecretRef,\n version: \"latest\",\n };\n delete nextEnv.GITHUB_APP_PRIVATE_KEY_FILE;\n } else if (input.githubApp.privateKeyFile) {\n nextEnv.GITHUB_APP_PRIVATE_KEY_FILE = input.githubApp.privateKeyFile;\n delete nextEnv.GITHUB_APP_PRIVATE_KEY;\n }\n if (JSON.stringify(nextEnv) === JSON.stringify(currentEnv)) {\n return null;\n }\n return { ...adapterConfig, env: nextEnv };\n }\n\n if (!isMatchingGitHubAppEnvBindings(currentEnv, input.githubApp)) {\n return null;\n }\n\n const nextEnv = { ...currentEnv };\n delete nextEnv.GITHUB_APP_ID;\n delete nextEnv.GITHUB_INSTALLATION_ID;\n delete nextEnv.GITHUB_APP_PRIVATE_KEY;\n delete nextEnv.GITHUB_APP_PRIVATE_KEY_FILE;\n const nextAdapterConfig = { ...adapterConfig };\n if (Object.keys(nextEnv).length > 0) {\n nextAdapterConfig.env = nextEnv;\n } else {\n delete nextAdapterConfig.env;\n }\n return nextAdapterConfig;\n}\n\nfunction isMatchingGitHubAppEnvBindings(env: Record<string, unknown>, githubApp: GitHubAppPropagationConfig): boolean {\n if (env.GITHUB_APP_ID !== githubApp.appId || env.GITHUB_INSTALLATION_ID !== githubApp.installationId) {\n return false;\n }\n if (githubApp.privateKeySecretRef) {\n return isMatchingSecretRefEnvBinding(env.GITHUB_APP_PRIVATE_KEY, githubApp.privateKeySecretRef);\n }\n return Boolean(githubApp.privateKeyFile && env.GITHUB_APP_PRIVATE_KEY_FILE === githubApp.privateKeyFile);\n}\n\nfunction isMatchingSecretRefEnvBinding(value: unknown, secretId: string): boolean {\n return isRecord(value) && value.type === \"secret_ref\" && value.secretId === secretId;\n}\n\nasync function fetchJson(path: string, init?: RequestInit): Promise<unknown> {\n const response = await fetch(path, {\n ...init,\n credentials: \"include\",\n headers: {\n accept: \"application/json\",\n ...(init?.body ? { \"content-type\": \"application/json\" } : {}),\n ...init?.headers,\n },\n });\n if (!response.ok) {\n throw new Error(`${response.status} ${response.statusText}`.trim());\n }\n return await response.json();\n}\n\nfunction getAgentFieldHint(input: {\n companyId: string;\n agentsLoading: boolean;\n agentsError: unknown;\n hasAgentOptions: boolean;\n}): string {\n if (!input.companyId) {\n return \"No company context is available, so paste the Paperclip agent UUID manually.\";\n }\n if (input.agentsLoading) {\n return \"Loading Paperclip agents...\";\n }\n if (input.agentsError) {\n return \"Could not load Paperclip agents; paste the agent UUID manually.\";\n }\n if (!input.hasAgentOptions) {\n return \"No Paperclip agents were found for this company; paste the agent UUID manually.\";\n }\n return \"The Paperclip agent that will use this identity.\";\n}\n\nconst responsiveSettingsStyle = `\n.agent-identities-settings,\n.agent-identities-settings * {\n box-sizing: border-box;\n}\n\n.agent-identities-summary-grid {\n grid-template-columns: repeat(3, minmax(0, 1fr));\n}\n\n.agent-identities-list-header,\n.agent-identities-list-row {\n grid-template-columns: minmax(0, 1fr) 8rem 8rem 13rem;\n}\n\n.agent-identities-row-actions {\n justify-content: flex-end;\n}\n\n.agent-identities-wizard-steps {\n grid-template-columns: repeat(3, minmax(0, 1fr));\n}\n\n@container (max-width: 720px) {\n .agent-identities-list-header {\n display: none !important;\n }\n\n .agent-identities-list-row {\n grid-template-columns: minmax(0, 1fr) auto;\n }\n\n .agent-identities-list-row > :nth-child(1) {\n grid-column: 1;\n grid-row: 1;\n }\n\n .agent-identities-list-row > :nth-child(2) {\n grid-column: 1 / -1;\n grid-row: 2;\n }\n\n .agent-identities-list-row > :nth-child(3) {\n grid-column: 2;\n grid-row: 1;\n }\n\n .agent-identities-list-row > :nth-child(4) {\n grid-column: 1 / -1;\n grid-row: 3;\n justify-content: flex-start;\n }\n}\n\n@container (max-width: 520px) {\n .agent-identities-summary-grid,\n .agent-identities-wizard-steps {\n grid-template-columns: minmax(0, 1fr);\n }\n}\n`;\n\nconst pageStyle: CSSProperties = {\n width: \"100%\",\n minWidth: 0,\n maxWidth: 1160,\n display: \"grid\",\n gap: \"1rem\",\n color: uiText,\n containerType: \"inline-size\",\n};\n\nconst pageTitleStyle: CSSProperties = {\n margin: 0,\n fontSize: \"1.125rem\",\n lineHeight: 1.2,\n letterSpacing: \"-0.02em\",\n};\n\nconst headerStyle: CSSProperties = {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"flex-start\",\n gap: \"1rem\",\n flexWrap: \"wrap\",\n};\n\nconst descriptionStyle: CSSProperties = {\n margin: \"0.35rem 0 0\",\n color: uiMutedText,\n fontSize: \"0.875rem\",\n};\n\nconst summaryGridStyle: CSSProperties = {\n display: \"grid\",\n gap: \"0.75rem\",\n};\n\nfunction summaryTileStyle(tone: IdentityTone): CSSProperties {\n return {\n display: \"grid\",\n gap: \"0.25rem\",\n padding: \"0.85rem 1rem\",\n border: `1px solid ${toneBorder(tone)}`,\n borderRadius: 12,\n backgroundColor: toneBackground(tone),\n };\n}\n\nconst summaryValueStyle: CSSProperties = {\n fontSize: \"1.125rem\",\n fontWeight: 700,\n lineHeight: 1,\n};\n\nconst summaryLabelStyle: CSSProperties = {\n color: uiMutedText,\n fontSize: \"0.8125rem\",\n fontWeight: 600,\n};\n\nconst credentialErrorStyle: CSSProperties = {\n padding: \"0.75rem 0.9rem\",\n backgroundColor: \"color-mix(in srgb, var(--agent-identities-danger) 12%, transparent)\",\n border: \"1px solid color-mix(in srgb, var(--agent-identities-danger) 45%, transparent)\",\n borderRadius: 10,\n color: uiDanger,\n fontSize: \"0.875rem\",\n};\n\nconst sectionStyle: CSSProperties = {\n minWidth: 0,\n border: `1px solid ${uiBorder}`,\n borderRadius: 14,\n padding: \"1rem\",\n display: \"grid\",\n gap: \"0.9rem\",\n backgroundColor: uiSurface,\n};\n\nconst sectionHeaderStyle: CSSProperties = {\n display: \"flex\",\n alignItems: \"flex-start\",\n justifyContent: \"space-between\",\n gap: \"1rem\",\n flexWrap: \"wrap\",\n};\n\nconst sectionTitleStyle: CSSProperties = {\n margin: 0,\n fontSize: \"0.875rem\",\n lineHeight: 1.25,\n};\n\nconst sectionDescriptionStyle: CSSProperties = {\n margin: \"0.25rem 0 0\",\n color: uiMutedText,\n fontSize: \"0.875rem\",\n};\n\nconst listStyle: CSSProperties = {\n display: \"grid\",\n gap: \"0.35rem\",\n minWidth: 0,\n};\n\nconst listHeaderStyle: CSSProperties = {\n display: \"grid\",\n gap: \"0.75rem\",\n padding: \"0 0.75rem 0.25rem\",\n color: uiMutedText,\n fontSize: \"0.8125rem\",\n fontWeight: 650,\n};\n\nconst rowStyle: CSSProperties = {\n display: \"grid\",\n gap: \"0.75rem\",\n alignItems: \"center\",\n border: `1px solid ${uiBorder}`,\n borderRadius: 10,\n padding: \"0.75rem\",\n backgroundColor: uiPanel,\n};\n\nconst rowTitleStyle: CSSProperties = {\n fontWeight: 650,\n overflowWrap: \"anywhere\",\n};\n\nconst rowMetaStyle: CSSProperties = {\n color: uiMutedText,\n fontSize: \"0.875rem\",\n overflowWrap: \"anywhere\",\n};\n\nconst rowActionsStyle: CSSProperties = {\n display: \"flex\",\n gap: \"0.5rem\",\n flexWrap: \"wrap\",\n};\n\nconst emptyStateStyle: CSSProperties = {\n display: \"grid\",\n justifyItems: \"start\",\n gap: \"0.5rem\",\n padding: \"1.25rem\",\n border: `1px dashed ${uiBorderStrong}`,\n borderRadius: 12,\n color: uiMutedText,\n backgroundColor: uiPanel,\n};\n\nconst dialogBackdropStyle: CSSProperties = {\n position: \"fixed\",\n inset: 0,\n zIndex: 1000,\n display: \"grid\",\n placeItems: \"start center\",\n padding: \"7vh 1rem 1rem\",\n backgroundColor: uiOverlay,\n overflowY: \"auto\",\n};\n\nconst dialogStyle: CSSProperties = {\n width: \"min(760px, 100%)\",\n maxHeight: \"86vh\",\n display: \"grid\",\n gridTemplateRows: \"auto minmax(0, 1fr) auto\",\n border: `1px solid ${uiBorder}`,\n borderRadius: 16,\n backgroundColor: uiCanvas,\n color: uiText,\n boxShadow: `0 24px 80px ${uiShadow}`,\n overflow: \"hidden\",\n};\n\nconst dialogHeaderStyle: CSSProperties = {\n display: \"flex\",\n alignItems: \"flex-start\",\n justifyContent: \"space-between\",\n gap: \"1rem\",\n padding: \"1.1rem 1.25rem 0.9rem\",\n borderBottom: `1px solid ${uiBorder}`,\n};\n\nconst dialogTitleStyle: CSSProperties = {\n margin: 0,\n fontSize: \"1.125rem\",\n lineHeight: 1.2,\n letterSpacing: \"-0.015em\",\n};\n\nconst closeButtonStyle: CSSProperties = {\n width: 32,\n height: 32,\n border: `1px solid ${uiBorder}`,\n borderRadius: 8,\n backgroundColor: \"transparent\",\n color: uiMutedText,\n cursor: \"pointer\",\n fontSize: \"0.875rem\",\n};\n\nconst dialogBodyStyle: CSSProperties = {\n display: \"grid\",\n gap: \"0.85rem\",\n padding: \"1rem 1.25rem\",\n overflowY: \"auto\",\n};\n\nconst wizardStepListStyle: CSSProperties = {\n display: \"grid\",\n gap: \"0.5rem\",\n};\n\nfunction wizardStepStyle(active: boolean): CSSProperties {\n return {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"0.5rem\",\n minHeight: 36,\n padding: \"0.45rem 0.6rem\",\n border: `1px solid ${active ? uiBorderStrong : uiBorder}`,\n borderRadius: 8,\n backgroundColor: active ? uiSurface : \"transparent\",\n color: active ? uiText : uiMutedText,\n fontSize: \"0.875rem\",\n fontWeight: active ? 600 : 500,\n };\n}\n\nfunction wizardStepNumberStyle(active: boolean, complete: boolean): CSSProperties {\n return {\n display: \"inline-grid\",\n placeItems: \"center\",\n width: 22,\n height: 22,\n borderRadius: 999,\n border: `1px solid ${complete ? uiSuccess : active ? uiBorderStrong : uiBorder}`,\n backgroundColor: complete ? \"color-mix(in srgb, var(--agent-identities-success) 14%, transparent)\" : uiPanel,\n color: complete ? uiSuccess : active ? uiText : uiMutedText,\n fontSize: \"0.8125rem\",\n fontWeight: 600,\n };\n}\n\nconst dialogFooterStyle: CSSProperties = {\n display: \"flex\",\n justifyContent: \"flex-end\",\n alignItems: \"center\",\n gap: \"0.75rem\",\n flexWrap: \"wrap\",\n padding: \"0.9rem 1.25rem\",\n borderTop: `1px solid ${uiBorder}`,\n backgroundColor: uiPanel,\n};\n\nconst saveStatusStyle: CSSProperties = {\n marginRight: \"auto\",\n fontSize: \"0.875rem\",\n};\n\nexport const validationNoticeStyle: CSSProperties = {\n padding: \"0.65rem 0.75rem\",\n border: \"1px solid color-mix(in srgb, var(--agent-identities-warning) 36%, transparent)\",\n borderRadius: 8,\n backgroundColor: \"color-mix(in srgb, var(--agent-identities-warning) 8%, transparent)\",\n color: uiText,\n fontSize: \"0.875rem\",\n};\n\nexport const fieldsetStyle: CSSProperties = {\n border: `1px solid ${uiBorder}`,\n borderRadius: 12,\n padding: \"1rem\",\n display: \"grid\",\n gap: \"0.75rem\",\n};\n\nexport const legendStyle: CSSProperties = {\n padding: \"0 0.25rem\",\n color: uiText,\n fontSize: \"0.875rem\",\n fontWeight: 600,\n};\n\nexport const fieldStyle: CSSProperties = {\n display: \"grid\",\n gap: \"0.35rem\",\n fontSize: \"0.875rem\",\n fontWeight: 600,\n};\n\nexport const inputStyle: CSSProperties = {\n minHeight: 38,\n padding: \"0.45rem 0.65rem\",\n border: `1px solid ${uiBorderStrong}`,\n borderRadius: 8,\n fontSize: \"0.875rem\",\n backgroundColor: uiInput,\n color: uiText,\n};\n\nexport const textareaStyle: CSSProperties = {\n ...inputStyle,\n fontFamily: \"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace\",\n};\n\nexport const detailsBodyStyle: CSSProperties = {\n display: \"grid\",\n gap: \"0.75rem\",\n marginTop: \"0.75rem\",\n};\n\nexport const manifestPanelStyle: CSSProperties = {\n display: \"grid\",\n gap: \"0.75rem\",\n padding: \"0.85rem\",\n border: `1px dashed ${uiBorderStrong}`,\n borderRadius: 10,\n backgroundColor: uiPanel,\n};\n\nexport const linkStyle: CSSProperties = {\n color: uiLink,\n fontWeight: 600,\n};\n\nexport const inlineNoticeStyle: CSSProperties = {\n padding: \"0.75rem 0.9rem\",\n border: `1px solid ${uiBorder}`,\n borderRadius: 10,\n backgroundColor: uiPanel,\n color: uiMutedText,\n fontSize: \"0.875rem\",\n};\n\nexport const hintStyle: CSSProperties = {\n fontSize: \"0.8125rem\",\n fontWeight: 400,\n color: uiMutedText,\n};\n\nexport const formActionsStyle: CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"0.75rem\",\n flexWrap: \"wrap\",\n};\n\nconst primaryButtonStyle: CSSProperties = {\n minHeight: 38,\n padding: \"0.48rem 0.9rem\",\n backgroundColor: uiPrimary,\n color: uiPrimaryText,\n border: `1px solid ${uiBorderStrong}`,\n borderRadius: 8,\n cursor: \"pointer\",\n fontWeight: 650,\n};\n\nexport const secondaryButtonStyle: CSSProperties = {\n minHeight: 34,\n padding: \"0.4rem 0.75rem\",\n backgroundColor: uiSurface,\n color: uiText,\n border: `1px solid ${uiBorderStrong}`,\n borderRadius: 8,\n cursor: \"pointer\",\n fontWeight: 600,\n};\n\nconst dangerButtonStyle: CSSProperties = {\n ...secondaryButtonStyle,\n color: uiDanger,\n};\n\nexport const requiredStyle: CSSProperties = {\n color: uiDanger,\n};\n\nexport const successStyle: CSSProperties = {\n color: uiSuccess,\n};\n\nexport const errorStyle: CSSProperties = {\n color: uiDanger,\n};\n\nfunction statusBadgeStyle(tone: IdentityTone): CSSProperties {\n return {\n justifySelf: \"start\",\n border: `1px solid ${toneBorder(tone)}`,\n borderRadius: 999,\n padding: \"0.2rem 0.55rem\",\n color: toneText(tone),\n backgroundColor: toneBackground(tone),\n fontSize: \"0.8125rem\",\n fontWeight: 650,\n whiteSpace: \"nowrap\",\n };\n}\n\nfunction buttonStyle(base: CSSProperties, disabled: boolean): CSSProperties {\n return disabled ? { ...base, opacity: 0.55, cursor: \"not-allowed\" } : base;\n}\n\nfunction toneText(tone: IdentityTone): string {\n if (tone === \"good\") return uiSuccess;\n if (tone === \"warn\") return uiWarning;\n return uiMutedText;\n}\n\nfunction toneBorder(tone: IdentityTone): string {\n if (tone === \"good\") return \"color-mix(in srgb, var(--agent-identities-success) 42%, transparent)\";\n if (tone === \"warn\") return \"color-mix(in srgb, var(--agent-identities-warning) 48%, transparent)\";\n return uiBorder;\n}\n\nfunction toneBackground(tone: IdentityTone): string {\n if (tone === \"good\") return \"color-mix(in srgb, var(--agent-identities-success) 10%, transparent)\";\n if (tone === \"warn\") return \"color-mix(in srgb, var(--agent-identities-warning) 12%, transparent)\";\n return uiPanel;\n}\n", "import type {\n AgentIdentityConfig,\n AgentIdentitySettingsState,\n GitHubAgentIdentityConfig,\n} from \"../core/identity-config.js\";\n\nexport type IdentityProviderId = \"github\" | \"slack\" | \"mattermost\" | \"entra\" | \"gcp\" | \"aws\";\n\nexport type IdentityProviderStatus = \"enabled\" | \"coming-soon\";\n\nexport type IdentityProviderDefinition = {\n id: IdentityProviderId;\n name: string;\n description: string;\n status: IdentityProviderStatus;\n};\n\nexport const GITHUB_IDENTITY_PROVIDER_ID = \"github\" satisfies IdentityProviderId;\nexport const SLACK_IDENTITY_PROVIDER_ID = \"slack\" satisfies IdentityProviderId;\nexport const REBIND_LEGACY_SLACK_CREDENTIALS_ACTION = \"rebind-legacy-slack-credentials\";\nexport const RETRY_LEGACY_SLACK_SIDECAR_CLEANUP_ACTION = \"retry-legacy-slack-sidecar-cleanup\";\n\nexport const SUPPORTED_IDENTITY_PROVIDERS: readonly IdentityProviderDefinition[] = [\n {\n id: \"github\",\n name: \"GitHub\",\n description: \"GitHub App identity for repositories, pull requests, branch pushes, and commit attribution.\",\n status: \"enabled\",\n },\n {\n id: \"slack\",\n name: \"Slack\",\n description: \"Workspace identity for Slack messages and app-mediated actions.\",\n status: \"coming-soon\",\n },\n {\n id: \"mattermost\",\n name: \"Mattermost\",\n description: \"Team identity for Mattermost posts and channel operations.\",\n status: \"coming-soon\",\n },\n {\n id: \"entra\",\n name: \"Microsoft Entra\",\n description: \"Cloud directory identity for Microsoft Graph and Azure-backed workflows.\",\n status: \"coming-soon\",\n },\n {\n id: \"gcp\",\n name: \"Google Cloud\",\n description: \"Service account identity for Google Cloud APIs.\",\n status: \"coming-soon\",\n },\n {\n id: \"aws\",\n name: \"AWS\",\n description: \"IAM-backed identity for AWS APIs.\",\n status: \"coming-soon\",\n },\n] as const;\n\nexport function isIdentityProviderId(value: string): value is IdentityProviderId {\n return SUPPORTED_IDENTITY_PROVIDERS.some((provider) => provider.id === value);\n}\n\nexport function getIdentityProviderDefinition(providerId: IdentityProviderId): IdentityProviderDefinition {\n return SUPPORTED_IDENTITY_PROVIDERS.find((provider) => provider.id === providerId)!;\n}\n\nexport function getIdentityKey(agentId: string, provider: string): string {\n return `${agentId.trim()}:${provider}`;\n}\n\nexport type { AgentIdentityConfig, AgentIdentitySettingsState };\n\nexport type BotIdentityConfig = AgentIdentityConfig;\n\nexport type BotIdentityGitHubAppCredentialConfig = {\n appId?: string;\n installationId?: string;\n privateKeySecretId?: string;\n privateKeyFile?: string;\n};\n\nexport type BotIdentityCredentialConfig = {\n /** Fallback token secret source. Prefer githubApp. */\n secretId?: string;\n /** Fallback short-lived token file source. Prefer githubApp. */\n tokenFile?: string;\n githubApp?: BotIdentityGitHubAppCredentialConfig;\n};\n\nexport type BotIdentitySettingsState = AgentIdentitySettingsState;\n\nexport type BotIdentitySlackSetup = {\n eventsRequestUrl?: string;\n botTokenSecretId?: string;\n signingSecretId?: string;\n legacyCredential?: LegacySlackCredentialStatus;\n};\n\nexport type LegacySlackCredentialStatus = {\n status: \"rebind-required\" | \"cleanup-pending\" | \"conflict\";\n signingSecretRequired: boolean;\n};\n\nexport type BotIdentitySettingsEntry = BotIdentityConfig & {\n credential?: BotIdentityCredentialConfig;\n /** Safe Slack setup projection. Contains secret UUID references, never secret values. */\n slackSetup?: BotIdentitySlackSetup;\n credentialStatus:\n | \"configured\"\n | \"missing\"\n | \"sidecar-unavailable\"\n | LegacySlackCredentialStatus[\"status\"];\n};\n\nexport type BotIdentitySettingsData = {\n version: 5;\n identities: BotIdentitySettingsEntry[];\n providers: readonly IdentityProviderDefinition[];\n companyName?: string;\n credentialSidecarPath: string;\n credentialSidecarError?: string;\n cleanupPending: LegacySlackSidecarCleanupStatus[];\n};\n\nexport type LegacySlackSidecarCleanupStatus = {\n cleanupId: string;\n companyId: string;\n provider: \"slack\";\n agentId: string;\n operation: \"legacy-sidecar-delete\";\n source: \"identity-delete\" | \"legacy-rebind\";\n};\n\nexport type RetryLegacySlackSidecarCleanupInput = {\n cleanupId?: string;\n agentId?: string;\n};\n\nexport type RetryLegacySlackSidecarCleanupResult = {\n cleanupId: string;\n provider: \"slack\";\n agentId: string;\n status: \"cleaned\";\n settings: BotIdentitySettingsData;\n};\n\nexport type DeleteBotIdentityConfigResult = BotIdentitySettingsData;\n\nexport type LegacySlackCleanupPendingData = {\n cleanupPending: Array<{\n cleanupId: string;\n provider: \"slack\";\n agentId: string;\n operation: \"legacy-sidecar-delete\";\n }>;\n};\n\ntype DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;\n\nexport type SaveBotIdentityConfigInput = DistributiveOmit<BotIdentityConfig, \"id\"> & {\n id?: string;\n previousAgentId?: string;\n credential?: BotIdentityCredentialConfig;\n};\n\nexport type DeleteBotIdentityConfigInput = {\n agentId: string;\n provider: IdentityProviderId;\n};\n\nexport type PaperclipAgentOption = {\n id: string;\n name: string;\n role?: string | null;\n title?: string | null;\n status?: string | null;\n};\n\nexport type PaperclipAgentsData = {\n agents: PaperclipAgentOption[];\n};\n\nexport type GitHubAppManifestFlowState = {\n agentId: string;\n provider: IdentityProviderId;\n state: string;\n manifest: string;\n postUrl: string;\n setupUrl: string;\n createdAt: string;\n label: string;\n appName: string;\n conversion?: ConvertGitHubAppManifestResult;\n};\n\nexport type CreateGitHubAppManifestInput = {\n agentId: string;\n provider?: IdentityProviderId;\n label: string;\n homepageUrl?: string;\n callbackUrl?: string;\n};\n\nexport type CreateGitHubAppManifestResult = GitHubAppManifestFlowState & {\n appName: string;\n};\n\nexport type GetGitHubAppManifestFlowInput = {\n state: string;\n consume?: boolean;\n};\n\nexport type GetGitHubAppManifestFlowResult = CreateGitHubAppManifestResult;\n\nexport type ConvertGitHubAppManifestInput = {\n state: string;\n code: string;\n};\n\nexport type ConvertGitHubAppManifestResult = {\n agentId: string;\n provider: IdentityProviderId;\n appId: string;\n appSlug: string;\n appName: string;\n githubUsername: string;\n privateKeyFile: string;\n installUrl: string;\n};\n\nexport type SlackAppManifestFlowState = {\n agentId: string;\n provider: IdentityProviderId;\n companyId: string;\n state: string;\n manifest: string;\n // Plain link to the Slack \"create app\" page. Slack does not support a\n // documented query parameter to prefill a manifest, so this is NOT a deep\n // link into a prefilled form \u2014 the operator must paste `manifest` in\n // manually via the \"From an app manifest\" flow. See\n // openwiki/domain/slack-provider-design.md.\n createAppUrl: string;\n createdAt: string;\n expiresAt: string;\n label: string;\n eventsRequestUrl: string;\n consumed?: boolean;\n};\n\nexport type CreateSlackAppManifestInput = {\n agentId: string;\n provider?: IdentityProviderId;\n label: string;\n eventsRequestUrl: string;\n};\n\nexport type CreateSlackAppManifestResult = {\n agentId: string;\n provider: IdentityProviderId;\n state: string;\n manifest: string;\n createAppUrl: string;\n createdAt: string;\n expiresAt: string;\n label: string;\n eventsRequestUrl: string;\n};\n\nexport type GetSlackAppManifestFlowInput = {\n state: string;\n};\n\nexport type GetSlackAppManifestFlowResult = CreateSlackAppManifestResult;\n\nexport type DiscoverSlackInstallMetadataInput = {\n botTokenSecretId: string;\n};\n\nexport type DiscoverSlackInstallMetadataResult = {\n teamId: string;\n botUserId: string;\n appId: string;\n};\n\nexport type LegacySlackCredentialRebindInput = {\n agentId: string;\n signingSecretId?: string;\n};\n\nexport type LegacySlackCredentialRebindResult = {\n agentId: string;\n provider: \"slack\";\n status: \"rebound\" | \"cleanup-pending\";\n};\n\nexport type SaveSlackInstallMetadataInput = {\n state: string;\n agentId: string;\n teamId: string;\n appId: string;\n botUserId: string;\n defaultChannel?: string;\n botTokenSecretId: string;\n signingSecretId: string;\n};\n\nexport type SaveSlackInstallMetadataResult = {\n agentId: string;\n provider: IdentityProviderId;\n teamId: string;\n appId: string;\n botUserId: string;\n eventsRequestUrl: string;\n botTokenSecretId: string;\n signingSecretId: string;\n defaultChannel?: string;\n status: \"saved\";\n};\n\nexport const DEFAULT_BOT_IDENTITY_CONFIG: GitHubAgentIdentityConfig = {\n provider: GITHUB_IDENTITY_PROVIDER_ID,\n id: \"\",\n agentId: \"\",\n label: \"\",\n github: { username: \"\" },\n};\n", "export const slackBotWhoamiToolName = \"slack_bot_whoami\";\n\nexport const slackBotWhoamiToolMetadata = {\n displayName: \"Slack Identity Who Am I\",\n description: \"Returns the calling agent's configured Slack identity metadata.\",\n parametersSchema: {\n type: \"object\",\n properties: {},\n additionalProperties: false\n }\n} as const;\n\nexport const slackBotWhoamiManifestTool = {\n name: slackBotWhoamiToolName,\n ...slackBotWhoamiToolMetadata\n} as const;\n", "// The Settings-UI analogue of `provider-contract.ts` / `provider-registry.ts`.\n// Those describe the *worker-side* tool surface each identity provider\n// contributes; this describes the *operator Settings UI wizard* surface each\n// provider contributes -- its wizard steps and per-step validation. Composed\n// once in `src/providers/index.ts` alongside `ALL_PROVIDERS`, so\n// `src/ui/SettingsPage.tsx` calls into a registry instead of branching on\n// provider id string literals.\n//\n// Deliberately generic over the same `IdentityFormState`-shaped config the UI\n// already uses (see `src/ui/SettingsPage.tsx`) rather than each provider's own\n// `TIdentity` type from `provider-contract.ts` -- the wizard form holds fields\n// for every provider at once (github + slack), so the adapter validates a\n// subset of that shared shape rather than a narrowed provider-specific type.\n\nexport type ProviderSettingsFormSection = string;\n\nexport interface ProviderSettingsFormStep {\n readonly id: ProviderSettingsFormSection;\n readonly label: string;\n}\n\nexport interface ProviderSettingsValidation {\n readonly identityComplete: boolean;\n readonly credentialComplete: boolean;\n readonly isComplete: boolean;\n readonly identityMessage: string;\n readonly credentialMessage: string;\n readonly saveMessage: string;\n}\n\n// The wizard form holds fields for every provider at once (github + slack),\n// so this is the full set an adapter may read from -- a structural superset\n// matching `IdentityFormState` in `src/ui/SettingsPage.tsx`. Kept here\n// (rather than importing `IdentityFormState` from the UI module) so this\n// contract has no dependency on the UI, avoiding a UI -> provider -> UI cycle.\nexport interface ProviderSettingsFormConfig {\n readonly agentId: string;\n readonly provider: string;\n readonly label: string;\n readonly githubUsername: string;\n readonly githubAppId: string;\n readonly githubInstallationId: string;\n readonly privateKeySecretId: string;\n readonly privateKeyFile: string;\n readonly fallbackTokenSecretId: string;\n readonly tokenFile: string;\n readonly slackTeamId: string;\n readonly slackAppId: string;\n readonly slackBotUserId: string;\n readonly slackDefaultChannel: string;\n readonly slackEventsRequestUrl: string;\n readonly slackBotTokenSecretId: string;\n readonly slackSigningSecretId: string;\n readonly slackLegacyCredentialStatus: string;\n readonly slackLegacySigningSecretRequired: string;\n}\n\n// Provider-specific async/in-flight state the shared component tracks (e.g.\n// Slack's last save-install-metadata result + busy flag) that a pure function\n// can't derive from `config` alone. Optional/union-friendly since most\n// providers (e.g. GitHub) need none of it.\nexport interface ProviderSettingsValidationExtra {\n readonly slackSaveResult?: {\n teamId: string;\n appId: string;\n botUserId: string;\n eventsRequestUrl: string;\n botTokenSecretId: string;\n signingSecretId: string;\n defaultChannel?: string | null;\n } | null;\n readonly slackSaveBusy?: boolean;\n}\n\nexport interface ProviderSettingsAdapter {\n readonly providerId: string;\n /** Ordered wizard steps shown for this provider (after the shared \"identity\" step). */\n readonly formSteps: readonly ProviderSettingsFormStep[];\n /**\n * The step id (from `formSteps`) that holds this provider's\n * credential/setup fields -- e.g. `\"github\"` or `\"slack\"`. Used by the\n * shared wizard to know which step to jump back to when save-time\n * validation fails on the credential half of the form, without the\n * component itself branching on provider id.\n */\n readonly credentialStepId: ProviderSettingsFormSection;\n /**\n * True when this provider persists its identity via its own dedicated\n * action (e.g. Slack's save-slack-install-metadata) rather than the shared\n * save-bot-identity-config action. When true, reaching the final wizard\n * step with `isComplete` means that dedicated action has already run, so\n * the shared \"Save agent\" step just closes the wizard instead of calling\n * save-bot-identity-config.\n */\n readonly savesViaSeparateAction: boolean;\n /**\n * True when the shared \"Identity\" step should also render this provider's\n * inline account field(s) (e.g. GitHub's username field). False when the\n * provider account details live entirely in the provider's own credential\n * step (e.g. Slack's \"Slack App\" step).\n */\n readonly hasProviderAccountFieldsInIdentityStep: boolean;\n getValidation(\n config: ProviderSettingsFormConfig,\n hasDuplicate: boolean,\n extra: ProviderSettingsValidationExtra,\n ): ProviderSettingsValidation;\n}\n\nexport interface ProviderSettingsRegistry {\n /** Look up the adapter for a provider id, falling back to `defaultProviderId`'s adapter if unknown. */\n get(providerId: string): ProviderSettingsAdapter;\n all(): readonly ProviderSettingsAdapter[];\n}\n\nexport function buildProviderSettingsRegistry(\n adapters: readonly ProviderSettingsAdapter[],\n defaultProviderId: string,\n): ProviderSettingsRegistry {\n const ordered = [...adapters];\n const byId = new Map(ordered.map((adapter) => [adapter.providerId, adapter] as const));\n const fallback = byId.get(defaultProviderId) ?? ordered[0];\n if (!fallback) {\n throw new Error(\"buildProviderSettingsRegistry: at least one adapter is required\");\n }\n return {\n get(providerId: string): ProviderSettingsAdapter {\n return byId.get(providerId) ?? fallback;\n },\n all(): readonly ProviderSettingsAdapter[] {\n return ordered;\n },\n };\n}\n", "import type {\n ProviderSettingsAdapter,\n ProviderSettingsValidation,\n} from \"../../core/provider-settings-contract.js\";\n// Deliberately NOT importing from \"./index.js\" (the github provider's\n// server-side composition, which pulls in app-manifest.ts's `node:crypto`\n// usage and the full worker tool surface) -- this module is imported by the\n// client-side Settings UI bundle (src/ui/SettingsPage.tsx ->\n// src/providers/index.ts -> this file), so it must only depend on\n// UI-safe/isomorphic modules. The provider id literal is duplicated here\n// (rather than imported from github/index.ts's GITHUB_PROVIDER_ID) to keep\n// this adapter's only dependency the UI contract type -- matching the\n// \"module-local constant\" pattern github/index.ts itself uses.\nconst GITHUB_SETTINGS_PROVIDER_ID = \"github\";\n\nexport const githubSettingsAdapter: ProviderSettingsAdapter = {\n providerId: GITHUB_SETTINGS_PROVIDER_ID,\n formSteps: [\n { id: \"identity\", label: \"Identity\" },\n { id: \"github\", label: \"GitHub App\" },\n { id: \"commit\", label: \"Commit\" },\n ],\n credentialStepId: \"github\",\n savesViaSeparateAction: false,\n hasProviderAccountFieldsInIdentityStep: true,\n getValidation(config, hasDuplicate): ProviderSettingsValidation {\n const hasIdentity =\n Boolean(config.agentId.trim() && config.provider.trim() && config.label.trim() && config.githubUsername.trim()) &&\n !hasDuplicate;\n const hasGitHubAppCredential = Boolean(\n config.githubAppId.trim() &&\n config.githubInstallationId.trim() &&\n (config.privateKeySecretId.trim() || config.privateKeyFile.trim()),\n );\n const hasFallbackCredential = Boolean(config.fallbackTokenSecretId.trim() || config.tokenFile.trim());\n const identityComplete = hasIdentity;\n const credentialComplete = hasGitHubAppCredential || hasFallbackCredential;\n const identityMessage = hasDuplicate\n ? \"This agent already has an identity for the selected provider. Edit the existing identity instead.\"\n : !hasIdentity\n ? \"Choose an agent, provider, label, and provider username before continuing.\"\n : \"Identity details are complete.\";\n const credentialMessage = credentialComplete\n ? \"Credential source is complete.\"\n : \"Add a complete GitHub App credential, or choose a fallback token source, before this identity can be saved.\";\n const saveMessage = !identityComplete\n ? identityMessage\n : !credentialComplete\n ? credentialMessage\n : \"Required setup is complete. Review optional commit metadata, then save.\";\n return {\n identityComplete,\n credentialComplete,\n isComplete: identityComplete && credentialComplete,\n identityMessage,\n credentialMessage,\n saveMessage,\n };\n },\n};\n", "import type {\n ProviderSettingsAdapter,\n ProviderSettingsValidation,\n} from \"../../core/provider-settings-contract.js\";\n// Deliberately NOT importing from \"./index.js\" (the slack provider's\n// server-side composition, which pulls in app-manifest.ts's `node:crypto`\n// usage) -- see the matching note in ../github/settings-adapter.ts. This\n// module is imported by the client-side Settings UI bundle.\nconst SLACK_SETTINGS_PROVIDER_ID = \"slack\";\n\nexport const slackSettingsAdapter: ProviderSettingsAdapter = {\n providerId: SLACK_SETTINGS_PROVIDER_ID,\n formSteps: [\n { id: \"identity\", label: \"Identity\" },\n { id: \"slack\", label: \"Slack App\" },\n ],\n credentialStepId: \"slack\",\n savesViaSeparateAction: true,\n hasProviderAccountFieldsInIdentityStep: false,\n getValidation(config, hasDuplicate, extra): ProviderSettingsValidation {\n const slackSaveResult = extra.slackSaveResult ?? null;\n const slackSaveBusy = Boolean(extra.slackSaveBusy);\n const hasIdentity = Boolean(config.agentId.trim() && config.provider.trim() && config.label.trim()) && !hasDuplicate;\n const hasSlackInstallFields = Boolean(\n config.slackTeamId.trim() &&\n config.slackAppId.trim() &&\n config.slackBotUserId.trim() &&\n config.slackBotTokenSecretId.trim() &&\n config.slackSigningSecretId.trim(),\n );\n // The install metadata is only considered saved when save-slack-install-metadata\n // has actually completed for the CURRENT field values -- editing any Slack field\n // after a successful save invalidates that prior result, and a save still in\n // flight must not let the footer report completion early.\n const slackSaveMatchesCurrentFields = Boolean(\n slackSaveResult &&\n slackSaveResult.teamId === config.slackTeamId.trim() &&\n slackSaveResult.appId === config.slackAppId.trim() &&\n slackSaveResult.botUserId === config.slackBotUserId.trim() &&\n slackSaveResult.eventsRequestUrl === config.slackEventsRequestUrl.trim() &&\n slackSaveResult.botTokenSecretId === config.slackBotTokenSecretId.trim() &&\n slackSaveResult.signingSecretId === config.slackSigningSecretId.trim() &&\n (slackSaveResult.defaultChannel ?? \"\") === config.slackDefaultChannel.trim(),\n );\n const hasSlackInstall = hasSlackInstallFields && slackSaveMatchesCurrentFields && !slackSaveBusy;\n const identityComplete = hasIdentity;\n const credentialComplete = hasSlackInstall;\n const identityMessage = hasDuplicate\n ? \"This agent already has an identity for the selected provider. Edit the existing identity instead.\"\n : !hasIdentity\n ? \"Choose an agent, provider, and label before continuing.\"\n : \"Identity details are complete.\";\n const credentialMessage = credentialComplete\n ? \"Slack install metadata is complete.\"\n : slackSaveBusy\n ? \"Saving Slack install metadata...\"\n : \"Create the Slack App manifest, install it, and paste back the team/app/bot IDs plus bot token and signing secret references, then save install metadata before this identity can be saved.\";\n const saveMessage = !identityComplete\n ? identityMessage\n : !credentialComplete\n ? credentialMessage\n : \"Required setup is complete.\";\n return {\n identityComplete,\n credentialComplete,\n isComplete: identityComplete && credentialComplete,\n identityMessage,\n credentialMessage,\n saveMessage,\n };\n },\n};\n", "// src/providers/settings-index.ts\n//\n// The Settings-UI analogue of src/providers/index.ts. Deliberately a SEPARATE\n// module (not added to providers/index.ts) because that file imports the\n// concrete `IdentityProvider` implementations (githubProvider, slackProvider,\n// ...), which pull in server-only code (e.g. app-manifest.ts's `node:crypto`\n// usage, credential resolution touching the filesystem). This file is\n// imported by the client-side Settings UI bundle\n// (src/ui/SettingsPage.tsx -> this file), so it must only depend on the\n// per-provider `settings-adapter.ts` modules, which are themselves UI-safe.\n//\n// Adding a settings-capable provider = add its `settings-adapter.ts` module\n// and append it to ALL_SETTINGS_ADAPTERS here.\nimport { githubSettingsAdapter } from \"./github/settings-adapter.js\";\nimport { slackSettingsAdapter } from \"./slack/settings-adapter.js\";\n\nexport const ALL_SETTINGS_ADAPTERS = [githubSettingsAdapter, slackSettingsAdapter] as const;\n", "// The React-rendering analogue of `provider-settings-contract.ts`. That file\n// describes a provider's wizard steps + pure validation; this describes the\n// provider's actual credential-step UI -- the local state/refs/effects/\n// handlers a provider needs to render its own fieldset, plus the JSX itself.\n//\n// Composed by a per-provider \"settings-adapter-ui.tsx\" module (client code,\n// may import React/hooks/JSX -- unlike settings-adapter.ts which must stay\n// UI-safe but framework-agnostic) and looked up via a small registry in\n// `src/providers/settings-ui-index.ts`, mirroring how\n// `provider-settings-contract.ts` adapters are looked up via\n// `settings-index.ts`. This lets `src/ui/SettingsPage.tsx` mount the active\n// provider's credential step without branching on provider id strings.\nimport type { ComponentType } from \"react\";\nimport type { ProviderSettingsValidationExtra } from \"./provider-settings-contract.js\";\n\n// Minimal shared surface the UI adapter's hook needs from SettingsPage. Kept\n// intentionally small and structural (not importing IdentityFormState\n// directly) to avoid a UI -> provider -> UI import cycle; providers depend on\n// this contract module, not on SettingsPage.tsx.\nexport interface ProviderSettingsUIFormConfig {\n readonly agentId: string;\n readonly provider: string;\n readonly label: string;\n readonly previousAgentId: string;\n}\n\nexport interface ProviderSettingsUIHookInput<TConfig extends ProviderSettingsUIFormConfig> {\n /** The current wizard form config, or null when no identity dialog is open. */\n readonly config: TConfig | null;\n /** Whether the current agent/provider pair exists in persisted settings. */\n readonly hasPersistedIdentity: boolean;\n /** Update a single form field, mirroring SettingsPage's `updateField`. */\n readonly updateField: (field: keyof TConfig & string, value: string) => void;\n /** Re-fetch identities/config after a mutation (mirrors usePluginData's `refresh`). */\n readonly refresh: () => void;\n /** The `delete-bot-identity-config` plugin action, used to clean up a renamed identity's stale row. */\n readonly deleteConfig: (input: Record<string, unknown>) => Promise<unknown>;\n /** Patch form state after a successful save (e.g. recording the just-saved agentId as `previousAgentId`). */\n readonly patchFormState: (patch: (prev: TConfig) => TConfig) => void;\n readonly secretOptions: ReadonlyArray<{ id: string; name: string; key?: string; description?: string; provider?: string; status?: string }>;\n readonly secretsLoading: boolean;\n readonly secretsError: string | null;\n readonly companyId: string;\n}\n\n// Whatever a provider's hook returns must include enough for the shared page\n// to gate the \"Next\"/\"Save\" footer buttons and to reset provider-owned state\n// from `startCreate`/`startEdit`/agentId-or-label-change -- everything else\n// (busy flags, manifest state, error strings, JSX props) is provider-owned\n// and opaque to SettingsPage.\nexport interface ProviderSettingsUIHookResult {\n /** Matches `ProviderSettingsAdapter.getValidation`'s `extra` parameter. */\n readonly validationExtra: ProviderSettingsValidationExtra;\n /**\n * Reset all provider-owned local state (busy flags, manifest flow, errors,\n * generation counters). Called by the shared page on startCreate,\n * startEdit, and whenever the agentId or label field changes.\n */\n readonly reset: () => void;\n}\n\nexport interface ProviderSettingsUIAdapter<\n TConfig extends ProviderSettingsUIFormConfig = ProviderSettingsUIFormConfig,\n THookResult extends ProviderSettingsUIHookResult = ProviderSettingsUIHookResult,\n // Providers whose credential step needs its own dedicated worker actions\n // (e.g. Slack's create-slack-app-manifest / get-slack-app-manifest-flow /\n // save-slack-install-metadata) extend the hook input with those action\n // callables. usePluginAction must be called at a component's top level, so\n // SettingsPage calls it and threads the callables in here rather than this\n // module importing plugin-sdk itself.\n THookInput extends ProviderSettingsUIHookInput<TConfig> = ProviderSettingsUIHookInput<TConfig>,\n> {\n readonly providerId: string;\n /** Hook capturing this provider's credential-step local state + handlers. */\n useCredentialStep(input: THookInput): THookResult;\n /** Renders this provider's credential-step fieldset JSX, given the hook's result. */\n readonly CredentialStep: ComponentType<{ state: THookResult; config: TConfig }>;\n /**\n * Optional per-provider recovery-guidance copy for the removal confirmation\n * dialog (see SettingsPage.tsx's `handleDelete`). This lets each provider\n * explain what deleting an identity does and does not do (e.g. Slack's\n * install metadata is only unlinked, not the Slack App/bot token itself)\n * without SettingsPage special-casing `provider === \"slack\"` -- it falls\n * back to generic copy when a provider doesn't implement this. Deliberately\n * takes only the minimal structural fields shared across every\n * `BotIdentitySettingsEntry` variant, not a provider-specific config type,\n * since removal is decided from the identities list row, not the wizard.\n */\n getRemovalConfirmation?(entry: { label: string; agentId: string; provider: string }): string;\n}\n\n// Each provider's UI adapter is generic over its own config/hook-result/\n// hook-input shape (e.g. Slack's manifest flow + secret fields), so a\n// registry holding adapters for *every* provider at once can't be typed any\n// more precisely than `any` here without erasing the very generics each\n// adapter module relies on -- callers narrow via a same-module cast (see\n// SettingsPage.tsx's use of `SlackSettingsUIFormConfig`) the same way the\n// existing `ProviderSettingsAdapter` registry callers narrow with `as`.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyProviderSettingsUIAdapter = ProviderSettingsUIAdapter<any, any, any>;\n\nexport interface ProviderSettingsUIRegistry {\n get(providerId: string): AnyProviderSettingsUIAdapter | undefined;\n}\n\nexport function buildProviderSettingsUIRegistry(\n adapters: readonly AnyProviderSettingsUIAdapter[],\n): ProviderSettingsUIRegistry {\n const byId = new Map(adapters.map((adapter) => [adapter.providerId, adapter] as const));\n return {\n get(providerId: string): AnyProviderSettingsUIAdapter | undefined {\n return byId.get(providerId);\n },\n };\n}\n", "import { useEffect, useRef, useState } from \"react\";\nimport type { ProviderSettingsUIAdapter, ProviderSettingsUIHookInput, ProviderSettingsUIHookResult } from \"../../core/provider-settings-ui-contract.js\";\nimport {\n SLACK_IDENTITY_PROVIDER_ID,\n type CreateSlackAppManifestResult,\n type DiscoverSlackInstallMetadataResult,\n type GetSlackAppManifestFlowResult,\n type LegacySlackCredentialRebindResult,\n type SaveSlackInstallMetadataResult,\n} from \"../../shared/types.js\";\nimport {\n errorStyle,\n fieldStyle,\n fieldsetStyle,\n formActionsStyle,\n hintStyle,\n inlineNoticeStyle,\n inputStyle,\n legendStyle,\n linkStyle,\n manifestPanelStyle,\n requiredStyle,\n secondaryButtonStyle,\n successStyle,\n textareaStyle,\n validationNoticeStyle,\n} from \"../../ui/SettingsPage.js\";\n\n// Deliberately NOT importing from \"./index.js\" (the slack provider's\n// server-side composition -- see the matching note in settings-adapter.ts).\n// This module is client code (JSX/hooks are fine to import here, unlike\n// settings-adapter.ts), but it must still avoid pulling in server-only code\n// (node:crypto, app-manifest.ts) into the client Settings UI bundle.\n\nexport interface SlackSettingsUIFormConfig {\n agentId: string;\n provider: string;\n label: string;\n previousAgentId: string;\n slackTeamId: string;\n slackAppId: string;\n slackBotUserId: string;\n slackDefaultChannel: string;\n slackEventsRequestUrl: string;\n slackBotTokenSecretId: string;\n slackSigningSecretId: string;\n slackLegacyCredentialStatus: string;\n slackLegacySigningSecretRequired: string;\n [key: string]: string;\n}\n\nexport interface SlackSettingsUIHookResult extends ProviderSettingsUIHookResult {\n slackManifestFlow: CreateSlackAppManifestResult | null;\n slackManifestBusy: boolean;\n slackSaveBusy: boolean;\n slackManifestError: string | null;\n slackSaveResult: SaveSlackInstallMetadataResult | null;\n slackManifestCopied: boolean;\n slackDiscoveryBusy: boolean;\n slackDiscoveryError: string | null;\n setSlackManifestCopied: (value: boolean) => void;\n setSlackManifestError: (value: string | null) => void;\n slackResumeStateInput: string;\n setSlackResumeStateInput: (value: string) => void;\n slackResumeBusy: boolean;\n slackResumeError: string | null;\n handleResumeSlackAppManifestFlow: () => Promise<void>;\n handleCreateSlackAppManifest: () => Promise<void>;\n handleDiscoverSlackInstallMetadata: () => Promise<void>;\n handleSaveSlackInstallMetadata: () => Promise<void>;\n // Retry-only path for finding #2: when save-slack-install-metadata succeeds\n // but the follow-up deleteConfig(previousAgentId) rebind cleanup fails, the\n // new identity is already persisted and the one-time manifest flow is\n // already consumed/deleted -- there is no \"state\" left to retry the save\n // itself. slackCleanupPendingAgentId names the stale identity that still\n // needs deleting; handleRetrySlackCleanup re-attempts only that delete\n // without touching the (already-saved) install metadata.\n slackCleanupPendingAgentId: string | null;\n slackCleanupBusy: boolean;\n slackCleanupError: string | null;\n handleRetrySlackCleanup: () => Promise<void>;\n // Capability/identity status readout via the credential-free\n // `slack_bot_whoami` tool (DRO-972). Never surfaces the bot token or any\n // other secret -- only the public id/name/status fields the tool itself\n // returns (see src/providers/slack/tools/whoami.ts).\n slackStatus: SlackBotWhoamiData | null;\n slackStatusLoading: boolean;\n slackStatusError: string | null;\n handleCheckSlackStatus: () => Promise<void>;\n hasPersistedIdentity: boolean;\n // Reinstall: re-runs the manifest-assisted setup flow against an existing\n // identity row, confirmation-gated. Reuses handleCreateSlackAppManifest;\n // mirrors GitHub's \"Replace this GitHub App\" collapsed-details pattern.\n handleReinstallSlackApp: () => Promise<void>;\n legacySlackRebindBusy: boolean;\n legacySlackRebindError: string | null;\n legacySlackRebindResult: LegacySlackCredentialRebindResult | null;\n handleLegacySlackRebind: () => Promise<void>;\n updateField: (field: keyof SlackSettingsUIFormConfig & string, value: string) => void;\n secretOptions: ReadonlyArray<{ id: string; name: string; key?: string; description?: string; provider?: string; status?: string }>;\n secretsLoading: boolean;\n secretsError: string | null;\n companyId: string;\n}\n\n// Only the non-secret identity/status fields `slack_bot_whoami` returns (see\n// src/providers/slack/tools/whoami.ts's `perform`) -- deliberately excludes\n// anything resembling a bot token, signing secret, or other credential.\nexport interface SlackBotWhoamiData {\n label?: string;\n teamId?: string;\n appId?: string;\n botUserId?: string;\n hasDefaultChannel?: boolean;\n}\n\nconst SLACK_MANIFEST_STATE_STORAGE_PREFIX = \"paperclip-agent-identities:slack-app-manifest-state:\";\n\nexport function normalizeSlackAppIdInput(value: string): string {\n const trimmed = value.trim();\n if (/^A[A-Z0-9]+$/i.test(trimmed)) {\n return trimmed.toUpperCase();\n }\n try {\n const url = new URL(trimmed);\n const path = url.pathname.split(\"/\").filter(Boolean);\n const appId = path[0] === \"apps\" ? path[1] : undefined;\n if (url.hostname === \"api.slack.com\" && appId && /^A[A-Z0-9]+$/i.test(appId)) {\n return appId.toUpperCase();\n }\n } catch {\n // Keep partially typed and non-URL values unchanged.\n }\n return value;\n}\n\nfunction actionErrorMessage(error: unknown, fallback: string): string {\n if (error instanceof Error && error.message.trim()) return error.message;\n if (typeof error === \"object\" && error !== null) {\n const message = (error as { message?: unknown }).message;\n if (typeof message === \"string\" && message.trim()) return message;\n }\n return fallback;\n}\n\n// The storage key is scoped by both companyId and agentId: sessionStorage is\n// shared across the whole origin, and operators can switch between companies\n// in the same browser session/tab without a reload. Without the companyId\n// segment, an in-progress Slack manifest flow for agent \"bot\" in company A\n// would be silently picked up (and potentially restored/resumed) while\n// viewing agent \"bot\" in company B.\nfunction getSlackManifestStateStorageKey(companyId: string, agentId: string): string {\n return `${SLACK_MANIFEST_STATE_STORAGE_PREFIX}${companyId}:${agentId}`;\n}\n\nfunction writeSlackManifestFlowState(companyId: string, agentId: string, state: string): void {\n try {\n window.sessionStorage.setItem(getSlackManifestStateStorageKey(companyId, agentId), state);\n } catch {\n // Persistence is best-effort; losing it only means the operator must\n // paste the state token manually via \"Resume an existing manifest flow\".\n }\n}\n\nfunction readSlackManifestFlowState(companyId: string, agentId: string): string | null {\n try {\n return window.sessionStorage.getItem(getSlackManifestStateStorageKey(companyId, agentId));\n } catch {\n return null;\n }\n}\n\nfunction deleteSlackManifestFlowState(companyId: string, agentId: string): void {\n try {\n window.sessionStorage.removeItem(getSlackManifestStateStorageKey(companyId, agentId));\n } catch {\n // Ignore sessionStorage cleanup failures.\n }\n}\n\nasync function copyTextToClipboard(value: string): Promise<void> {\n try {\n if (navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(value);\n return;\n }\n } catch {\n // Fall through to the legacy textarea-copy fallback below.\n }\n const textarea = document.createElement(\"textarea\");\n textarea.value = value;\n textarea.setAttribute(\"readonly\", \"\");\n textarea.style.position = \"fixed\";\n textarea.style.opacity = \"0\";\n document.body.appendChild(textarea);\n textarea.select();\n try {\n const copied = document.execCommand(\"copy\");\n if (!copied) {\n throw new Error(\"execCommand('copy') was rejected\");\n }\n } finally {\n textarea.remove();\n }\n}\n\ntype SlackCredentialStepInput = ProviderSettingsUIHookInput<SlackSettingsUIFormConfig> & SlackSettingsUIActionsInput;\n\nfunction useSlackCredentialStep(input: SlackCredentialStepInput): SlackSettingsUIHookResult {\n const { config, hasPersistedIdentity, updateField, refresh, deleteConfig, patchFormState, createSlackAppManifest, getSlackAppManifestFlow, discoverSlackInstallMetadata, saveSlackInstallMetadata, rebindLegacySlackCredentials, slackBotWhoami, companyId } = input;\n\n const [slackManifestFlow, setSlackManifestFlow] = useState<CreateSlackAppManifestResult | null>(null);\n const [slackManifestBusy, setSlackManifestBusy] = useState(false);\n const [slackSaveBusy, setSlackSaveBusy] = useState(false);\n const [slackManifestError, setSlackManifestError] = useState<string | null>(null);\n const [slackSaveResult, setSlackSaveResult] = useState<SaveSlackInstallMetadataResult | null>(null);\n const [slackManifestCopied, setSlackManifestCopied] = useState(false);\n const [slackDiscoveryBusy, setSlackDiscoveryBusy] = useState(false);\n const [slackDiscoveryError, setSlackDiscoveryError] = useState<string | null>(null);\n const [slackResumeStateInput, setSlackResumeStateInput] = useState(\"\");\n const [slackResumeBusy, setSlackResumeBusy] = useState(false);\n const [slackResumeError, setSlackResumeError] = useState<string | null>(null);\n const [slackStatus, setSlackStatus] = useState<SlackBotWhoamiData | null>(null);\n const [slackStatusLoading, setSlackStatusLoading] = useState(false);\n const [slackStatusError, setSlackStatusError] = useState<string | null>(null);\n const [legacySlackRebindBusy, setLegacySlackRebindBusy] = useState(false);\n const [legacySlackRebindError, setLegacySlackRebindError] = useState<string | null>(null);\n const [legacySlackRebindResult, setLegacySlackRebindResult] = useState<LegacySlackCredentialRebindResult | null>(null);\n const slackStatusGenerationRef = useRef(0);\n const slackDiscoveryGenerationRef = useRef(0);\n // Finding #2: when the post-save rebind cleanup (deleteConfig(previousAgentId))\n // fails, the new identity is already saved and the flow already\n // consumed/deleted -- there is no \"state\" to retry the save itself. Track\n // just the stale agentId that still needs deleting so the UI can offer a\n // cleanup-only retry instead of telling the operator to redo a save that\n // would fail (the flow is gone) or silently leaving an orphaned identity.\n const [slackCleanupPendingAgentId, setSlackCleanupPendingAgentId] = useState<string | null>(null);\n const [slackCleanupBusy, setSlackCleanupBusy] = useState(false);\n const [slackCleanupError, setSlackCleanupError] = useState<string | null>(null);\n // Holds the save-slack-install-metadata result that succeeded but whose\n // rebind cleanup (deleteConfig(previousAgentId)) failed, so a later\n // successful retry can still mark the save complete (setSlackSaveResult)\n // without re-calling save-slack-install-metadata (whose one-time `state`\n // is already consumed).\n const slackCleanupPendingResultRef = useRef<SaveSlackInstallMetadataResult | null>(null);\n const slackSaveGenerationRef = useRef(0);\n // Guards the Slack manifest-flow lifecycle (automatic restore-on-mount,\n // manual \"Restore flow\", and \"Create Slack App manifest\") the same way\n // slackSaveGenerationRef guards save-slack-install-metadata: any reset\n // (edit invalidation, dialog close/reopen, provider/agent switch) bumps\n // this so a stale create/restore response that arrives afterward is\n // discarded instead of being applied to a form it no longer matches.\n const slackManifestFlowGenerationRef = useRef(0);\n\n function reset() {\n setSlackManifestFlow(null);\n setSlackManifestError(null);\n setSlackSaveResult(null);\n setSlackManifestCopied(false);\n setSlackDiscoveryBusy(false);\n setSlackDiscoveryError(null);\n slackDiscoveryGenerationRef.current += 1;\n setSlackResumeStateInput(\"\");\n setSlackResumeError(null);\n // Bump the create/restore generation so any in-flight\n // create-slack-app-manifest / get-slack-app-manifest-flow response\n // started before this reset is discarded when it arrives (finding #4/#8).\n slackManifestFlowGenerationRef.current += 1;\n // Bumping the generation makes the pending create/restore requests'\n // `finally` blocks skip their own busy-flag cleanup (the generation\n // check fails), so this reset must clear those busy flags itself --\n // otherwise an agent/label reset or dialog reopen while a\n // create-slack-app-manifest / get-slack-app-manifest-flow /\n // resume request is in flight would leave the Slack setup controls\n // disabled permanently.\n setSlackManifestBusy(false);\n setSlackResumeBusy(false);\n // Also invalidate an in-flight save-slack-install-metadata request: a\n // reset (e.g. starting a new/different identity, or closing the dialog)\n // means a stale response should never attach to whatever form comes\n // next. Mirrors the same generation-guard pattern used on field edits.\n slackSaveGenerationRef.current += 1;\n setSlackSaveBusy(false);\n // A pending cleanup retry is scoped to the identity that was just being\n // edited when deleteConfig(previousAgentId) failed. Starting a new/\n // different identity or closing the dialog abandons that in-context\n // retry UI; the stale identity itself still exists server-side, but it\n // is no longer this form's concern once the dialog moves on.\n setSlackCleanupPendingAgentId(null);\n setSlackCleanupError(null);\n setSlackCleanupBusy(false);\n slackCleanupPendingResultRef.current = null;\n setSlackStatus(null);\n setSlackStatusError(null);\n setSlackStatusLoading(false);\n slackStatusGenerationRef.current += 1;\n setLegacySlackRebindBusy(false);\n setLegacySlackRebindError(null);\n setLegacySlackRebindResult(null);\n }\n\n // Any edit to the Slack install fields invalidates a prior successful\n // save-slack-install-metadata result -- it was only valid for the exact\n // field values it was saved with. Watching config's slack* fields (rather\n // than requiring SettingsPage to call back in on every updateField) keeps\n // this entirely provider-owned.\n const slackFieldsSignature = config\n ? `${config.slackTeamId}|${config.slackAppId}|${config.slackBotUserId}|${config.slackDefaultChannel}|${config.slackBotTokenSecretId}|${config.slackSigningSecretId}`\n : \"\";\n const prevSlackFieldsSignatureRef = useRef(slackFieldsSignature);\n useEffect(() => {\n if (prevSlackFieldsSignatureRef.current !== slackFieldsSignature) {\n prevSlackFieldsSignatureRef.current = slackFieldsSignature;\n setSlackSaveResult(null);\n slackSaveGenerationRef.current += 1;\n // The in-flight save (if any) is now stale and its finally() will no\n // longer match the current generation, so it will never clear\n // slackSaveBusy itself -- clear it here so the wizard doesn't get\n // stuck showing \"Saving...\" after an edit invalidates the request.\n setSlackSaveBusy(false);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [slackFieldsSignature]);\n\n const slackDiscoverySecretSignature = config?.slackBotTokenSecretId ?? \"\";\n const prevSlackDiscoverySecretSignatureRef = useRef(slackDiscoverySecretSignature);\n useEffect(() => {\n if (prevSlackDiscoverySecretSignatureRef.current === slackDiscoverySecretSignature) return;\n prevSlackDiscoverySecretSignatureRef.current = slackDiscoverySecretSignature;\n slackDiscoveryGenerationRef.current += 1;\n setSlackDiscoveryBusy(false);\n setSlackDiscoveryError(null);\n }, [slackDiscoverySecretSignature]);\n\n // Check the Slack capability/identity status via slack_bot_whoami whenever\n // this credential step mounts for a saved Slack identity (i.e. there's\n // something to check). Only runs for an already-configured identity --\n // there's nothing to look up yet for a brand-new one still being set up.\n useEffect(() => {\n if (!config || config.provider !== SLACK_IDENTITY_PROVIDER_ID) return;\n if (!hasPersistedIdentity || !config.agentId.trim()) {\n slackStatusGenerationRef.current += 1;\n setSlackStatus(null);\n setSlackStatusError(null);\n setSlackStatusLoading(false);\n return;\n }\n void handleCheckSlackStatus();\n // Re-check when a just-saved identity appears in refreshed settings, when\n // switching to a different persisted agent, or after a label edit resets\n // the provider-owned state. Form-field presence is not evidence that a\n // new wizard row has been saved yet.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [config?.agentId, config?.label, config?.provider, hasPersistedIdentity]);\n\n // Restore an in-progress Slack manifest flow after a reload or editor\n // reopen. Unlike GitHub, Slack has no redirect callback to carry state\n // back in via the URL, so the only place to look is the state token this\n // component persisted to sessionStorage when the flow was created (see\n // writeSlackManifestFlowState). Re-validate against the server (rather\n // than trusting the stored token blindly) since the flow may have expired\n // or been consumed since it was written.\n useEffect(() => {\n if (!config || config.provider !== SLACK_IDENTITY_PROVIDER_ID) return;\n if (slackManifestFlow) return;\n const agentId = config.agentId.trim();\n if (!agentId) return;\n const storedState = readSlackManifestFlowState(companyId, agentId);\n if (!storedState) return;\n\n let cancelled = false;\n const generation = slackManifestFlowGenerationRef.current;\n void getSlackAppManifestFlow({ state: storedState })\n .then((result) => {\n if (cancelled || slackManifestFlowGenerationRef.current !== generation) return;\n const flow = result as GetSlackAppManifestFlowResult;\n if (flow.agentId !== agentId) {\n deleteSlackManifestFlowState(companyId, agentId);\n return;\n }\n // The worker persists flow.label alongside flow.agentId (see\n // app-manifest.ts). If the label was edited (or the flow belongs to\n // a differently-labeled setup) since the flow was created, restoring\n // it silently would let the UI show one label while\n // save-slack-install-metadata records another. Reject a\n // label-mismatched flow rather than restoring it.\n if (config.label.trim() && flow.label && flow.label !== config.label.trim()) {\n deleteSlackManifestFlowState(companyId, agentId);\n return;\n }\n if (config.slackEventsRequestUrl.trim() && flow.eventsRequestUrl !== config.slackEventsRequestUrl.trim()) {\n deleteSlackManifestFlowState(companyId, agentId);\n return;\n }\n if (!config.slackEventsRequestUrl.trim()) {\n updateField(\"slackEventsRequestUrl\", flow.eventsRequestUrl);\n }\n setSlackManifestFlow(flow);\n setSlackManifestCopied(false);\n })\n .catch((err) => {\n if (cancelled) return;\n // Only drop the stored state pointer when the server has\n // definitively told us the flow is gone (unknown/expired/consumed --\n // see loadUnexpiredUnconsumedFlow in app-manifest.ts). A transient\n // failure (network error, bridge hiccup, unexpected 5xx) is not\n // proof the flow is invalid; deleting the pointer on those would\n // destroy the operator's only automatic resume path and force them\n // to create a whole new Slack App. Leave the pointer in place and\n // just surface the error so the next mount/retry can try again.\n const message = err instanceof Error ? err.message : String(err);\n const isDefinitivelyGone = /unknown or expired|already been used|has expired/i.test(message);\n if (isDefinitivelyGone) {\n deleteSlackManifestFlowState(companyId, agentId);\n } else {\n setSlackManifestError(\n `Could not restore the in-progress Slack App manifest flow (${message}). It has not been discarded - reload or try again.`,\n );\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [config, getSlackAppManifestFlow, slackManifestFlow, companyId]);\n\n async function handleResumeSlackAppManifestFlow() {\n if (!config) return;\n const state = slackResumeStateInput.trim();\n if (!state) return;\n const generation = slackManifestFlowGenerationRef.current;\n setSlackResumeBusy(true);\n setSlackResumeError(null);\n try {\n const flow = await getSlackAppManifestFlow({ state }) as GetSlackAppManifestFlowResult;\n // Discard this response if the dialog/form is no longer the one that\n // initiated the request (e.g. reset via a field edit, closing the\n // dialog, or starting a different identity while this was in flight).\n if (slackManifestFlowGenerationRef.current !== generation) return;\n if (flow.agentId !== config.agentId.trim()) {\n throw new Error(\"This state token belongs to a different agent than the one currently selected.\");\n }\n // Reconcile the flow's persisted label against the current form the\n // same way as the automatic-restore path: a mismatched label means\n // this flow was created for a different setup, so reject it rather\n // than silently binding a save to the wrong label.\n if (config.label.trim() && flow.label && flow.label !== config.label.trim()) {\n throw new Error(\"This state token belongs to a different label than the one currently entered.\");\n }\n if (config.slackEventsRequestUrl.trim() && flow.eventsRequestUrl !== config.slackEventsRequestUrl.trim()) {\n throw new Error(\"This state token belongs to a different Events Request URL than the one currently entered.\");\n }\n if (!config.slackEventsRequestUrl.trim()) {\n updateField(\"slackEventsRequestUrl\", flow.eventsRequestUrl);\n }\n setSlackManifestFlow(flow);\n setSlackManifestCopied(false);\n setSlackManifestError(null);\n writeSlackManifestFlowState(companyId, config.agentId.trim(), flow.state);\n } catch (err) {\n if (slackManifestFlowGenerationRef.current !== generation) return;\n setSlackResumeError(err instanceof Error ? err.message : \"Could not restore the Slack App manifest flow for that state token.\");\n } finally {\n if (slackManifestFlowGenerationRef.current === generation) {\n setSlackResumeBusy(false);\n }\n }\n }\n\n async function handleCreateSlackAppManifest() {\n if (!config) return;\n if (config.provider !== SLACK_IDENTITY_PROVIDER_ID) {\n setSlackManifestError(\"Slack App setup is only available for the Slack provider.\");\n return;\n }\n const generation = slackManifestFlowGenerationRef.current;\n setSlackManifestBusy(true);\n setSlackManifestError(null);\n setSlackSaveResult(null);\n try {\n const result = await createSlackAppManifest({\n agentId: config.agentId.trim(),\n provider: config.provider,\n label: config.label.trim(),\n eventsRequestUrl: config.slackEventsRequestUrl.trim(),\n }) as CreateSlackAppManifestResult;\n // Discard this response if the dialog/form that initiated the request\n // is no longer current (finding #4): a reset in between (edit, close,\n // switching identity) must not let a late create response attach to a\n // different form.\n if (slackManifestFlowGenerationRef.current !== generation) return;\n setSlackManifestFlow(result);\n setSlackManifestCopied(false);\n writeSlackManifestFlowState(companyId, config.agentId.trim(), result.state);\n } catch (err) {\n if (slackManifestFlowGenerationRef.current !== generation) return;\n setSlackManifestError(err instanceof Error ? err.message : \"Failed to create Slack App manifest\");\n } finally {\n if (slackManifestFlowGenerationRef.current === generation) {\n setSlackManifestBusy(false);\n }\n }\n }\n\n async function handleSaveSlackInstallMetadata() {\n if (!config || !slackManifestFlow) return;\n const generation = ++slackSaveGenerationRef.current;\n setSlackSaveBusy(true);\n setSlackManifestError(null);\n try {\n const targetAgentId = config.agentId.trim();\n const previousAgentId = config.previousAgentId.trim();\n const botTokenSecretId = config.slackBotTokenSecretId.trim();\n const signingSecretId = config.slackSigningSecretId.trim();\n const result = await saveSlackInstallMetadata({\n state: slackManifestFlow.state,\n agentId: targetAgentId,\n teamId: config.slackTeamId.trim(),\n appId: config.slackAppId.trim(),\n botUserId: config.slackBotUserId.trim(),\n botTokenSecretId,\n signingSecretId,\n ...(config.slackDefaultChannel.trim() ? { defaultChannel: config.slackDefaultChannel.trim() } : {}),\n }) as SaveSlackInstallMetadataResult;\n // Stale-response guard: if another save started (or the fields were\n // edited, invalidating slackSaveResult) after this request was sent,\n // a newer generation has already been assigned. Applying this result\n // anyway would let a late/aborted-in-spirit response silently mark\n // the (now different) form values as saved when the fields underneath\n // it may no longer match what was actually persisted server-side.\n if (slackSaveGenerationRef.current !== generation) {\n return;\n }\n // save-slack-install-metadata only upserts `${agentId}:slack`; it has\n // no knowledge of a rename. If the Agent field was changed while\n // editing an existing Slack identity, the old `${previousAgentId}:slack`\n // identity + credential would otherwise be orphaned, so clean it up\n // explicitly via the existing delete action.\n if (previousAgentId && previousAgentId !== targetAgentId) {\n try {\n await deleteConfig({ agentId: previousAgentId, provider: SLACK_IDENTITY_PROVIDER_ID });\n } catch (err) {\n // Do not mark this rebind complete: both the old and new\n // identities now exist server-side, so \"Save agent\" closing the\n // dialog here would silently leave the stale previousAgentId\n // identity behind with no obvious retry path. Surface the error\n // and leave slackSaveResult unset (credentialComplete stays\n // false) so the operator can retry, keeping the dialog open.\n //\n // Note: the install metadata itself IS already saved and the\n // one-time manifest flow is already consumed/deleted at this\n // point, so re-running handleSaveSlackInstallMetadata is not a\n // valid retry (its `state` no longer exists). Track the stale\n // agentId so the UI can offer a cleanup-only retry\n // (handleRetrySlackCleanup) instead.\n setSlackManifestError(\n `Slack install metadata saved, but could not remove the previous identity for ${previousAgentId}: ${err instanceof Error ? err.message : \"unknown error\"}. Use \"Retry cleanup\" below.`\n );\n setSlackCleanupPendingAgentId(previousAgentId);\n setSlackCleanupError(null);\n slackCleanupPendingResultRef.current = result;\n // The manifest's one-time state was already consumed by the\n // successful save above, even though the rebind cleanup failed.\n // Clear the in-memory flow now (not just the sessionStorage\n // pointer) so the credential step can no longer be re-submitted\n // against this already-consumed state -- e.g. by editing a field,\n // which would otherwise clear slackSaveResult and re-enable \"Save\n // Slack install metadata\" pointed at a flow that is guaranteed to\n // fail (finding: consumed-state resubmission).\n setSlackManifestFlow(null);\n deleteSlackManifestFlowState(companyId, targetAgentId);\n await refresh();\n // The new identity is already persisted even though removing the\n // previous identity failed. Re-check it now so the status panel\n // does not keep the pre-save \"identity unavailable\" result while\n // the operator uses the cleanup-only retry path.\n await handleCheckSlackStatus();\n return;\n }\n }\n setSlackSaveResult(result);\n // Clear the in-memory manifest flow (not just the sessionStorage\n // pointer) now that its one-time state has been consumed by this\n // successful save. Otherwise editing any Slack field afterward clears\n // slackSaveResult (via the signature effect) and re-enables \"Save\n // Slack install metadata\" while slackManifestFlow still looks active,\n // guaranteeing the retry fails against an already-consumed state.\n setSlackManifestFlow(null);\n deleteSlackManifestFlowState(companyId, targetAgentId);\n // Record the just-saved identity as the form's \"previous\" identity before\n // refreshing. Otherwise refresh() adds this identity to `identities`, and\n // duplicateIdentity (which compares against previousAgentId) would then\n // treat the freshly-saved identity as a duplicate of itself and disable\n // the footer's \"Save agent\" button.\n patchFormState((prev) => ({ ...prev, previousAgentId: result.agentId }));\n await refresh();\n // For an identity that was already persisted, hasPersistedIdentity\n // stays true across this save, so the mount/identity effect above has\n // no dependency transition to trigger a new lookup. Re-read the\n // configured metadata explicitly after the successful update. New\n // identities still use the false -> true persisted-state transition\n // after refresh, avoiding a duplicate lookup on their first save.\n if (hasPersistedIdentity) {\n await handleCheckSlackStatus();\n }\n } catch (err) {\n if (slackSaveGenerationRef.current !== generation) return;\n setSlackManifestError(err instanceof Error ? err.message : \"Failed to save Slack install metadata\");\n } finally {\n if (slackSaveGenerationRef.current === generation) {\n setSlackSaveBusy(false);\n }\n }\n }\n\n async function handleDiscoverSlackInstallMetadata() {\n if (!config) return;\n const botTokenSecretId = config.slackBotTokenSecretId.trim();\n if (!botTokenSecretId) return;\n const generation = ++slackDiscoveryGenerationRef.current;\n setSlackDiscoveryBusy(true);\n setSlackDiscoveryError(null);\n try {\n const result = await discoverSlackInstallMetadata({ botTokenSecretId }) as DiscoverSlackInstallMetadataResult;\n if (slackDiscoveryGenerationRef.current !== generation) return;\n const teamId = result.teamId?.trim();\n const botUserId = result.botUserId?.trim();\n const appId = result.appId?.trim();\n if (!teamId || !botUserId || !appId) {\n throw new Error(\"Slack did not return the workspace ID, App ID, and bot user ID for this token.\");\n }\n updateField(\"slackTeamId\", teamId);\n updateField(\"slackAppId\", appId);\n updateField(\"slackBotUserId\", botUserId);\n } catch (err) {\n if (slackDiscoveryGenerationRef.current !== generation) return;\n setSlackDiscoveryError(actionErrorMessage(err, \"Could not detect Slack installation metadata\"));\n } finally {\n if (slackDiscoveryGenerationRef.current === generation) {\n setSlackDiscoveryBusy(false);\n }\n }\n }\n\n // Cleanup-only retry for finding #2: re-attempt just the\n // deleteConfig(previousAgentId) rebind cleanup that failed after\n // save-slack-install-metadata already succeeded. Deliberately does not\n // re-call saveSlackInstallMetadata -- the manifest flow's one-time `state`\n // token is already consumed/deleted by the earlier successful save, so\n // retrying the save itself would fail with a stale/expired-flow error.\n async function handleRetrySlackCleanup() {\n const pendingAgentId = slackCleanupPendingAgentId;\n const pendingResult = slackCleanupPendingResultRef.current;\n if (!pendingAgentId || !pendingResult) return;\n // Reuse the save generation counter as a stale-response guard: reset()\n // (dialog close, agent/label/provider change, starting a different\n // identity) bumps it and clears the cleanup-pending state. If that\n // happens while this delete is in flight, the response below must not\n // apply patchFormState/setSlackSaveResult to whatever form is now\n // current (Copilot finding: cleanup retry has no stale-response guard).\n const generation = slackSaveGenerationRef.current;\n setSlackCleanupBusy(true);\n setSlackCleanupError(null);\n try {\n await deleteConfig({ agentId: pendingAgentId, provider: SLACK_IDENTITY_PROVIDER_ID });\n if (slackSaveGenerationRef.current !== generation) return;\n setSlackCleanupPendingAgentId(null);\n slackCleanupPendingResultRef.current = null;\n setSlackManifestError(null);\n // The install metadata was already saved by the original request; now\n // that cleanup has finally succeeded, mark the save complete so\n // credentialComplete/isComplete reflect reality.\n setSlackSaveResult(pendingResult);\n patchFormState((prev) => ({ ...prev, previousAgentId: pendingResult.agentId }));\n await refresh();\n } catch (err) {\n if (slackSaveGenerationRef.current !== generation) return;\n setSlackCleanupError(\n err instanceof Error ? err.message : `Failed to remove the previous identity for ${pendingAgentId}`,\n );\n } finally {\n if (slackSaveGenerationRef.current === generation) {\n setSlackCleanupBusy(false);\n }\n }\n }\n\n // Capability/identity status readout (DRO-976 increment #2): calls the\n // credential-free `slack_bot_whoami` tool the exact same way SettingsPage\n // obtains any other plugin action (usePluginAction), threaded in here as\n // `slackBotWhoami`. Only ever reads back the non-secret identity/status\n // fields the tool itself returns (see tools/whoami.ts's `perform`). The\n // bot token is resolved only inside the worker and never enters this response.\n async function handleCheckSlackStatus() {\n const agentId = config?.agentId?.trim();\n if (!agentId) return;\n const generation = ++slackStatusGenerationRef.current;\n setSlackStatusLoading(true);\n setSlackStatusError(null);\n try {\n const result = (await slackBotWhoami({ agentId, companyId })) as\n | { data?: SlackBotWhoamiData; error?: string }\n | SlackBotWhoamiData;\n if (slackStatusGenerationRef.current !== generation) return;\n // The action can *resolve* (not reject) with a `{ error }` shape when\n // the tool itself reports a handled failure (e.g. no bound identity).\n // Treat that the same as a thrown error -- never let a resolved\n // `{ error }` fall through to the configured-metadata render.\n const resultError = (result as { error?: unknown })?.error;\n if (resultError) {\n setSlackStatus(null);\n setSlackStatusError(typeof resultError === \"string\" ? resultError : \"Identity metadata unavailable\");\n return;\n }\n const data = (result as { data?: SlackBotWhoamiData })?.data ?? (result as SlackBotWhoamiData);\n setSlackStatus(data ?? null);\n } catch (err) {\n if (slackStatusGenerationRef.current !== generation) return;\n setSlackStatus(null);\n // Deliberately surface only the error message (never the raw\n // rejection payload/response), and fall back to a secret-free generic\n // \"Identity metadata unavailable\" message if the tool didn't provide one.\n setSlackStatusError(err instanceof Error ? err.message : \"Identity metadata unavailable\");\n } finally {\n if (slackStatusGenerationRef.current === generation) {\n setSlackStatusLoading(false);\n }\n }\n }\n\n // Confirmation-gated reinstall: re-runs the same manifest-assisted setup\n // flow as \"Create Slack App manifest\" (handleCreateSlackAppManifest),\n // against an already-configured identity row. Mirrors GitHub's \"Replace\n // this GitHub App with a new manifest-created app\" collapsed-details\n // pattern (settings-adapter-ui.tsx:467-480 in the GitHub adapter).\n async function handleReinstallSlackApp() {\n if (!config) return;\n const confirmed = window.confirm(\n \"Reinstall the Slack App for this identity? This creates a new Slack App manifest flow; you'll need to re-create/reinstall the app on Slack and paste back the resulting IDs and bot token secret.\",\n );\n if (!confirmed) return;\n await handleCreateSlackAppManifest();\n }\n\n async function handleLegacySlackRebind() {\n if (!config?.agentId.trim()) return;\n const signingSecretId = config.slackSigningSecretId.trim();\n if (config.slackLegacySigningSecretRequired === \"true\" && !signingSecretId) {\n setLegacySlackRebindError(\n \"Select or enter the Paperclip company secret UUID containing the Slack signing secret before rebinding.\",\n );\n return;\n }\n setLegacySlackRebindBusy(true);\n setLegacySlackRebindError(null);\n try {\n const result = await rebindLegacySlackCredentials({\n agentId: config.agentId.trim(),\n ...(signingSecretId ? { signingSecretId } : {}),\n }) as LegacySlackCredentialRebindResult;\n setLegacySlackRebindResult(result);\n await refresh();\n } catch (error) {\n setLegacySlackRebindResult(null);\n setLegacySlackRebindError(actionErrorMessage(error, \"Could not rebind released Slack credentials\"));\n } finally {\n setLegacySlackRebindBusy(false);\n }\n }\n\n return {\n validationExtra: { slackSaveResult, slackSaveBusy },\n reset,\n slackManifestFlow,\n slackManifestBusy,\n slackSaveBusy,\n slackManifestError,\n slackSaveResult,\n slackManifestCopied,\n slackDiscoveryBusy,\n slackDiscoveryError,\n setSlackManifestCopied,\n setSlackManifestError,\n slackResumeStateInput,\n setSlackResumeStateInput,\n slackResumeBusy,\n slackResumeError,\n handleResumeSlackAppManifestFlow,\n handleCreateSlackAppManifest,\n handleDiscoverSlackInstallMetadata,\n handleSaveSlackInstallMetadata,\n slackCleanupPendingAgentId,\n slackCleanupBusy,\n slackCleanupError,\n handleRetrySlackCleanup,\n slackStatus,\n slackStatusLoading,\n slackStatusError,\n handleCheckSlackStatus,\n hasPersistedIdentity,\n handleReinstallSlackApp,\n legacySlackRebindBusy,\n legacySlackRebindError,\n legacySlackRebindResult,\n handleLegacySlackRebind,\n updateField,\n secretOptions: input.secretOptions,\n secretsLoading: input.secretsLoading,\n secretsError: input.secretsError,\n companyId: input.companyId,\n };\n}\n\n// Slack's worker actions (create-slack-app-manifest, get-slack-app-manifest-flow,\n// save-slack-install-metadata) are obtained via `usePluginAction`, which must be\n// called at the top of a component -- not lazily inside this module. SettingsPage\n// calls usePluginAction for these three actions itself and threads the resulting\n// callables through the hook input so this file never has to import plugin-sdk\n// directly for actions it doesn't own the lifecycle of.\nexport interface SlackSettingsUIActionsInput {\n createSlackAppManifest: (input: Record<string, unknown>) => Promise<unknown>;\n getSlackAppManifestFlow: (input: Record<string, unknown>) => Promise<unknown>;\n discoverSlackInstallMetadata: (input: Record<string, unknown>) => Promise<unknown>;\n saveSlackInstallMetadata: (input: Record<string, unknown>) => Promise<unknown>;\n rebindLegacySlackCredentials: (input: Record<string, unknown>) => Promise<unknown>;\n // The credential-free `slack_bot_whoami` tool (DRO-972), invoked identically\n // to the actions above via `usePluginAction` in SettingsPage.\n slackBotWhoami: (input: Record<string, unknown>) => Promise<unknown>;\n}\n\nfunction getSecretFieldHint(input: {\n companyId: string;\n secretsLoading: boolean;\n secretsError: string | null;\n hasSecretOptions: boolean;\n}): string {\n if (!input.companyId) {\n return \"No company context is available, so paste the Paperclip secret UUID manually.\";\n }\n if (input.secretsLoading) {\n return \"Loading Paperclip secrets...\";\n }\n if (input.secretsError) {\n return `Could not load Paperclip secrets (${input.secretsError}); paste the secret UUID manually.`;\n }\n if (!input.hasSecretOptions) {\n return \"No Paperclip secrets were found; paste the bot token secret UUID manually.\";\n }\n return \"Saved as a Paperclip secret reference for the Slack bot token. There is no private-key or file fallback for Slack.\";\n}\n\nfunction getSigningSecretFieldHint(input: {\n companyId: string;\n secretsLoading: boolean;\n secretsError: string | null;\n hasSecretOptions: boolean;\n}): string {\n if (!input.companyId) {\n return \"No company context is available, so paste the Paperclip secret UUID manually.\";\n }\n if (input.secretsLoading) {\n return \"Loading Paperclip secrets...\";\n }\n if (input.secretsError) {\n return `Could not load Paperclip secrets (${input.secretsError}); paste the secret UUID manually.`;\n }\n if (!input.hasSecretOptions) {\n return \"No Paperclip secrets were found; paste the signing secret UUID manually.\";\n }\n return \"Saved as a Paperclip secret reference for Slack request signature verification.\";\n}\n\nfunction formatSecretOption(secret: { id: string; name: string; key?: string; description?: string; provider?: string; status?: string }): string {\n const label = secret.name || secret.key || secret.id;\n const details = [secret.key && secret.key !== label ? secret.key : null, secret.status, secret.provider]\n .filter(Boolean)\n .join(\" - \");\n return details ? `${label} (${details})` : label;\n}\n\nfunction SlackCredentialStep(props: { state: SlackSettingsUIHookResult; config: SlackSettingsUIFormConfig }) {\n const { state, config } = props;\n const {\n slackManifestFlow,\n slackManifestBusy,\n slackSaveBusy,\n slackManifestError,\n slackSaveResult,\n slackManifestCopied,\n slackDiscoveryBusy,\n slackDiscoveryError,\n setSlackManifestCopied,\n setSlackManifestError,\n slackResumeStateInput,\n setSlackResumeStateInput,\n slackResumeBusy,\n slackResumeError,\n handleResumeSlackAppManifestFlow,\n handleCreateSlackAppManifest,\n handleDiscoverSlackInstallMetadata,\n handleSaveSlackInstallMetadata,\n slackCleanupPendingAgentId,\n slackCleanupBusy,\n slackCleanupError,\n handleRetrySlackCleanup,\n slackStatus,\n slackStatusLoading,\n slackStatusError,\n handleReinstallSlackApp,\n legacySlackRebindBusy,\n legacySlackRebindError,\n legacySlackRebindResult,\n handleLegacySlackRebind,\n hasPersistedIdentity,\n validationExtra,\n updateField,\n secretOptions,\n secretsLoading,\n secretsError,\n companyId,\n } = state;\n const hasSecretOptions = secretOptions.length > 0;\n const credentialComplete = Boolean(\n slackSaveResult\n && slackSaveResult.teamId === config.slackTeamId.trim()\n && slackSaveResult.appId === config.slackAppId.trim()\n && slackSaveResult.botUserId === config.slackBotUserId.trim()\n && slackSaveResult.eventsRequestUrl === config.slackEventsRequestUrl.trim()\n && slackSaveResult.botTokenSecretId === config.slackBotTokenSecretId.trim()\n && slackSaveResult.signingSecretId === config.slackSigningSecretId.trim()\n && (slackSaveResult.defaultChannel ?? \"\") === config.slackDefaultChannel.trim()\n && !validationExtra.slackSaveBusy,\n );\n const hasLegacyCredentialRecovery = Boolean(config.slackLegacyCredentialStatus);\n\n return (\n <fieldset style={fieldsetStyle}>\n <legend style={legendStyle}>Slack App setup</legend>\n {hasPersistedIdentity && (\n <SlackStatusPanel\n agentId={config.agentId}\n label={config.label}\n loading={slackStatusLoading}\n status={slackStatus}\n error={slackStatusError}\n />\n )}\n {hasPersistedIdentity && config.slackLegacyCredentialStatus && (\n <LegacySlackCredentialRebindPanel\n status={config.slackLegacyCredentialStatus}\n signingSecretRequired={config.slackLegacySigningSecretRequired === \"true\"}\n signingSecretReady={Boolean(config.slackSigningSecretId.trim())}\n busy={legacySlackRebindBusy}\n error={legacySlackRebindError}\n result={legacySlackRebindResult}\n onRebind={handleLegacySlackRebind}\n />\n )}\n {!credentialComplete && !hasLegacyCredentialRecovery && (\n <div style={validationNoticeStyle}>\n Create the Slack App manifest, install it, and paste back the team/app/bot IDs plus bot token and signing\n secret references, then save install metadata before this identity can be saved. Do not verify the Request\n URL in Slack yet. Paperclip cannot answer Slack's verification challenge until the signing secret reference\n has been saved.\n </div>\n )}\n\n {!hasLegacyCredentialRecovery && <div style={inlineNoticeStyle}>\n <strong>Create a Slack App from a manifest.</strong> Slack does not support a prefilled deep link for manifests,\n so Paperclip generates the manifest JSON below for you to copy, then opens the plain Slack \"create app\" page\n where you paste it in via \"From an app manifest\".\n </div>}\n\n {!hasLegacyCredentialRecovery && <label style={fieldStyle}>\n <span>Events Request URL <span style={requiredStyle}>*</span></span>\n <input\n type=\"url\"\n value={config.slackEventsRequestUrl}\n onChange={(e) => updateField(\"slackEventsRequestUrl\", e.target.value)}\n placeholder=\"https://your-public-tunnel.example/events\"\n style={inputStyle}\n disabled={slackManifestBusy || slackSaveBusy || Boolean(slackManifestFlow)}\n />\n <span style={hintStyle}>\n Public HTTPS URL for the local Slack Events adapter. It must use the exact /events path.\n </span>\n </label>}\n\n {!hasPersistedIdentity && (\n <div style={formActionsStyle}>\n <button\n type=\"button\"\n onClick={() => void handleCreateSlackAppManifest()}\n disabled={\n slackManifestBusy ||\n slackSaveBusy ||\n slackResumeBusy ||\n !config.agentId ||\n !config.label ||\n !config.slackEventsRequestUrl.trim()\n }\n style={secondaryButtonStyle}\n >\n {slackManifestBusy ? \"Working...\" : \"Create Slack App manifest\"}\n </button>\n </div>\n )}\n\n {!hasLegacyCredentialRecovery && !slackManifestFlow && (\n <div style={formActionsStyle}>\n <label style={fieldStyle}>\n <span>Resume an existing manifest flow</span>\n <input\n type=\"text\"\n value={slackResumeStateInput}\n onChange={(e) => setSlackResumeStateInput(e.target.value)}\n placeholder=\"Paste the pc_... state token from a previous session\"\n style={inputStyle}\n />\n <span style={hintStyle}>\n Reloading settings or closing this editor loses the in-progress manifest flow from local state.\n If you saved the state token from when the manifest was created, paste it here to resume within\n its 30-minute server-side window instead of creating a new Slack App.\n </span>\n </label>\n <button\n type=\"button\"\n onClick={() => void handleResumeSlackAppManifestFlow()}\n disabled={slackResumeBusy || slackManifestBusy || slackSaveBusy || !slackResumeStateInput.trim()}\n style={secondaryButtonStyle}\n >\n {slackResumeBusy ? \"Restoring...\" : \"Restore flow\"}\n </button>\n </div>\n )}\n\n {slackResumeError && <span style={errorStyle}>{slackResumeError}</span>}\n\n {slackManifestFlow && (\n <div style={manifestPanelStyle}>\n <label style={fieldStyle}>\n <span>Manifest JSON</span>\n <textarea\n readOnly\n value={slackManifestFlow.manifest}\n style={{ ...textareaStyle, minHeight: 320, fontFamily: \"ui-monospace, SFMono-Regular, Menlo, monospace\" }}\n />\n </label>\n <div style={formActionsStyle}>\n <button\n type=\"button\"\n onClick={() =>\n void copyTextToClipboard(slackManifestFlow.manifest)\n .then(() => {\n setSlackManifestCopied(true);\n setSlackManifestError(null);\n })\n .catch(() => {\n setSlackManifestCopied(false);\n setSlackManifestError(\"Could not copy the manifest JSON to the clipboard. Select the text above and copy it manually.\");\n })\n }\n style={secondaryButtonStyle}\n >\n {slackManifestCopied ? \"Copied!\" : \"Copy manifest JSON\"}\n </button>\n <a href={slackManifestFlow.createAppUrl} target=\"_blank\" rel=\"noreferrer\" style={linkStyle}>Open Slack \"Create an app\" page</a>\n </div>\n <span style={hintStyle}>\n On the Slack page, choose \"From an app manifest,\" select the workspace, then paste the copied JSON. After\n Slack creates and you install the app, come back and paste the resulting IDs below. Slack may show the\n Request URL as unverified. Leave it unverified until you save the signing secret reference in Paperclip.\n </span>\n <label style={fieldStyle}>\n <span>Flow state token</span>\n <input type=\"text\" readOnly value={slackManifestFlow.state} style={inputStyle} />\n <span style={hintStyle}>\n Save this token if you might reload settings or close this editor before finishing setup. Paste it\n into \"Resume an existing manifest flow\" above to restore this in-progress flow within its\n 30-minute window.\n </span>\n </label>\n </div>\n )}\n\n {slackManifestError && <span style={errorStyle}>{slackManifestError}</span>}\n\n <label style={fieldStyle}>\n <span>Team ID <span style={requiredStyle}>*</span></span>\n <input\n type=\"text\"\n value={config.slackTeamId}\n onChange={(e) => updateField(\"slackTeamId\", e.target.value)}\n placeholder=\"e.g. T0123456789\"\n style={inputStyle}\n disabled={slackSaveBusy}\n />\n </label>\n\n <label style={fieldStyle}>\n <span>App ID <span style={requiredStyle}>*</span></span>\n <input\n type=\"text\"\n value={config.slackAppId}\n onChange={(e) => updateField(\"slackAppId\", normalizeSlackAppIdInput(e.target.value))}\n placeholder=\"A0123456789 or https://api.slack.com/apps/A0123456789/general\"\n style={inputStyle}\n disabled={slackSaveBusy}\n />\n <span style={hintStyle}>Paste the App ID or the Slack app settings URL. Paperclip extracts the App ID from the URL.</span>\n </label>\n\n <label style={fieldStyle}>\n <span>Bot User ID <span style={requiredStyle}>*</span></span>\n <input\n type=\"text\"\n value={config.slackBotUserId}\n onChange={(e) => updateField(\"slackBotUserId\", e.target.value)}\n placeholder=\"e.g. U0123456789\"\n style={inputStyle}\n disabled={slackSaveBusy}\n />\n </label>\n\n {!hasLegacyCredentialRecovery && <label style={fieldStyle}>\n <span>Bot token Paperclip secret UUID <span style={requiredStyle}>*</span></span>\n {hasSecretOptions ? (\n <select\n value={config.slackBotTokenSecretId}\n onChange={(e) => updateField(\"slackBotTokenSecretId\", e.target.value)}\n style={inputStyle}\n disabled={slackSaveBusy || slackDiscoveryBusy}\n >\n <option value=\"\">No bot token secret reference</option>\n {config.slackBotTokenSecretId && !secretOptions.some((secret) => secret.id === config.slackBotTokenSecretId) && (\n <option value={config.slackBotTokenSecretId}>{config.slackBotTokenSecretId} (saved)</option>\n )}\n {secretOptions.map((secret) => (\n <option key={secret.id} value={secret.id}>{formatSecretOption(secret)}</option>\n ))}\n </select>\n ) : (\n <input\n type=\"text\"\n value={config.slackBotTokenSecretId}\n onChange={(e) => updateField(\"slackBotTokenSecretId\", e.target.value)}\n placeholder=\"Company secret UUID containing the Slack bot token\"\n style={inputStyle}\n disabled={slackSaveBusy || slackDiscoveryBusy}\n />\n )}\n <span style={hintStyle}>{getSecretFieldHint({ companyId, secretsLoading, secretsError, hasSecretOptions })} The bot token itself is never stored in this config; only the secret reference is.</span>\n </label>}\n\n {!hasLegacyCredentialRecovery && <div style={formActionsStyle}>\n <button\n type=\"button\"\n onClick={() => void handleDiscoverSlackInstallMetadata()}\n disabled={slackSaveBusy || slackDiscoveryBusy || !config.slackBotTokenSecretId.trim()}\n style={secondaryButtonStyle}\n >\n {slackDiscoveryBusy ? \"Detecting...\" : \"Detect Slack installation IDs\"}\n </button>\n <span style={hintStyle}>\n Uses the selected bot token secret to fill Team ID, App ID, and Bot User ID.\n </span>\n </div>}\n {!hasLegacyCredentialRecovery && slackDiscoveryError && <span style={errorStyle}>{slackDiscoveryError}</span>}\n\n {(!hasLegacyCredentialRecovery || config.slackLegacySigningSecretRequired === \"true\") && <label style={fieldStyle}>\n <span>Signing secret Paperclip secret UUID <span style={requiredStyle}>*</span></span>\n {hasSecretOptions ? (\n <select\n value={config.slackSigningSecretId}\n onChange={(e) => updateField(\"slackSigningSecretId\", e.target.value)}\n style={inputStyle}\n disabled={slackSaveBusy}\n >\n <option value=\"\">No signing secret reference</option>\n {config.slackSigningSecretId && !secretOptions.some((secret) => secret.id === config.slackSigningSecretId) && (\n <option value={config.slackSigningSecretId}>{config.slackSigningSecretId} (saved)</option>\n )}\n {secretOptions.map((secret) => (\n <option key={secret.id} value={secret.id}>{formatSecretOption(secret)}</option>\n ))}\n </select>\n ) : (\n <input\n type=\"text\"\n value={config.slackSigningSecretId}\n onChange={(e) => updateField(\"slackSigningSecretId\", e.target.value)}\n placeholder=\"Company secret UUID containing the Slack signing secret\"\n style={inputStyle}\n disabled={slackSaveBusy}\n />\n )}\n <span style={hintStyle}>\n {getSigningSecretFieldHint({ companyId, secretsLoading, secretsError, hasSecretOptions })} The signing secret\n itself is never stored in this config; only the secret reference is.\n </span>\n </label>}\n\n <label style={fieldStyle}>\n <span>Default channel</span>\n <input\n type=\"text\"\n value={config.slackDefaultChannel}\n onChange={(e) => updateField(\"slackDefaultChannel\", e.target.value)}\n placeholder=\"e.g. C0123456789\"\n style={inputStyle}\n disabled={slackSaveBusy}\n />\n <span style={hintStyle}>Optional. Must be a Slack conversation ID starting with C, D, or G.</span>\n </label>\n\n {!hasLegacyCredentialRecovery && <div style={formActionsStyle}>\n <button\n type=\"button\"\n onClick={() => void handleSaveSlackInstallMetadata()}\n disabled={\n slackManifestBusy ||\n slackSaveBusy ||\n Boolean(slackCleanupPendingAgentId) ||\n !slackManifestFlow ||\n !config.slackTeamId.trim() ||\n !config.slackAppId.trim() ||\n !config.slackBotUserId.trim() ||\n !config.slackBotTokenSecretId.trim() ||\n !config.slackSigningSecretId.trim()\n }\n style={secondaryButtonStyle}\n >\n {slackSaveBusy ? \"Saving...\" : \"Save Slack install metadata\"}\n </button>\n </div>}\n\n {!hasLegacyCredentialRecovery && !slackManifestFlow && !slackCleanupPendingAgentId && !slackSaveResult && (\n <span style={hintStyle}>Create the manifest above first; saving install metadata requires an active manifest flow state.</span>\n )}\n\n {slackCleanupPendingAgentId && (\n <div style={validationNoticeStyle}>\n <div>\n Slack install metadata was saved, but Paperclip could not remove the previous identity for{\" \"}\n <strong>{slackCleanupPendingAgentId}</strong>. The new identity is safe; retry cleanup below rather than\n saving again (the manifest flow used for this save has already been consumed).\n </div>\n <div style={formActionsStyle}>\n <button\n type=\"button\"\n onClick={() => void handleRetrySlackCleanup()}\n disabled={slackCleanupBusy}\n style={secondaryButtonStyle}\n >\n {slackCleanupBusy ? \"Retrying...\" : \"Retry cleanup\"}\n </button>\n </div>\n {slackCleanupError && <span style={errorStyle}>{slackCleanupError}</span>}\n </div>\n )}\n\n {slackSaveResult && (\n <div style={successStyle}>\n Slack install metadata saved for team {slackSaveResult.teamId}. Return to Slack's App Manifest page now,\n verify the Request URL, and save the manifest changes. If verification failed before this save, retry it now.\n </div>\n )}\n\n {hasPersistedIdentity && !hasLegacyCredentialRecovery && (\n <details>\n <summary>Reinstall the Slack App for this identity</summary>\n <div style={{ display: \"grid\", gap: \"0.75rem\", marginTop: \"0.75rem\" }}>\n <div style={inlineNoticeStyle}>\n <strong>Reinstall from a manifest.</strong> This re-runs Slack App setup for this identity - creating a\n new manifest flow, requiring you to reinstall the app on Slack and paste back the resulting IDs and bot\n token secret. It does not remove the currently saved install metadata unless you save over it.\n </div>\n <div style={formActionsStyle}>\n <button\n type=\"button\"\n onClick={() => void handleReinstallSlackApp()}\n disabled={\n slackManifestBusy ||\n slackSaveBusy ||\n slackResumeBusy ||\n !config.slackEventsRequestUrl.trim()\n }\n style={secondaryButtonStyle}\n >\n {slackManifestBusy ? \"Working...\" : \"Reinstall\"}\n </button>\n </div>\n </div>\n </details>\n )}\n </fieldset>\n );\n}\n\nfunction LegacySlackCredentialRebindPanel(props: {\n status: string;\n signingSecretRequired: boolean;\n signingSecretReady: boolean;\n busy: boolean;\n error: string | null;\n result: LegacySlackCredentialRebindResult | null;\n onRebind: () => Promise<void>;\n}) {\n if (props.status === \"conflict\") {\n return (\n <div style={validationNoticeStyle}>\n <strong>Released Slack credentials need operator review.</strong> The existing company Slack binding conflicts\n with the public identity or released sidecar references. Paperclip will not overwrite it. Remove or correct\n the conflicting host binding, then reopen this identity and rebind; reinstall is not required.\n </div>\n );\n }\n\n const cleanupPending = props.status === \"cleanup-pending\" || props.result?.status === \"cleanup-pending\";\n return (\n <div style={cleanupPending ? inlineNoticeStyle : validationNoticeStyle}>\n <div>\n <strong>{cleanupPending ? \"Legacy Slack sidecar cleanup pending.\" : \"Upgrade action required.\"}</strong>{\" \"}\n {cleanupPending\n ? \"The company host binding is working. Retry to remove only the released Slack sidecar entry.\"\n : \"Slack v0.1.7/v0.1.8 saved credential UUID references in the local sidecar. Rebind copies those references into this company's authorized Slack config without reading either secret value.\"}\n {!cleanupPending && props.signingSecretRequired\n ? \" This released entry has no signing-secret reference; select or enter its Paperclip company secret UUID below first.\"\n : \"\"}\n </div>\n <div style={formActionsStyle}>\n <button\n type=\"button\"\n onClick={() => void props.onRebind()}\n disabled={props.busy || (props.signingSecretRequired && !props.signingSecretReady)}\n style={secondaryButtonStyle}\n >\n {props.busy ? \"Working...\" : cleanupPending ? \"Retry legacy cleanup\" : \"Rebind released credentials\"}\n </button>\n </div>\n {props.result?.status === \"rebound\" && <span style={successStyle}>Released Slack credentials rebound successfully. Close this editor; reinstall is not required.</span>}\n {props.error && <span style={errorStyle}>{props.error}</span>}\n </div>\n );\n}\n\nfunction SlackStatusPanel(props: {\n agentId: string;\n label: string;\n loading: boolean;\n status: SlackBotWhoamiData | null;\n error: string | null;\n}) {\n const { agentId, label, loading, status, error } = props;\n if (loading) {\n return <div style={inlineNoticeStyle}>Loading configured Slack identity metadata for {label || agentId}...</div>;\n }\n if (error) {\n // Deliberately renders only the (already-sanitized) error message, never\n // a raw payload -- see handleCheckSlackStatus's catch branch.\n return (\n <div style={validationNoticeStyle}>\n Slack identity metadata unavailable for agent <strong>{label || agentId}</strong> ({error}).\n </div>\n );\n }\n if (!status) {\n return null;\n }\n return (\n <div style={inlineNoticeStyle}>\n <strong>Configured Slack identity.</strong>{\" \"}\n Saved metadata for agent <strong>{label || agentId}</strong>: workspace {status.teamId ?? \"unknown\"}, app {status.appId ?? \"unknown\"},\n bot user {status.botUserId ?? \"unknown\"}\n {status.hasDefaultChannel ? \", default channel configured\" : \", no default channel configured\"}.\n {\" \"}This reflects saved install metadata only - it does not verify the bot token is still valid; a revoked or\n stale token is not detected here.\n </div>\n );\n}\n\nexport const slackSettingsUIAdapter: ProviderSettingsUIAdapter<SlackSettingsUIFormConfig, SlackSettingsUIHookResult, SlackCredentialStepInput> = {\n providerId: SLACK_IDENTITY_PROVIDER_ID,\n useCredentialStep: useSlackCredentialStep,\n CredentialStep: SlackCredentialStep,\n getRemovalConfirmation(entry) {\n return `Delete agent identity mapping for ${entry.label}? This clears saved Slack install metadata; your Slack app and bot token are not deleted, only unlinked from this agent. To reconnect later, create a new Slack mapping with \"Add identity\".`;\n },\n};\n", "import { useEffect, useRef, useState } from \"react\";\nimport type { ProviderSettingsUIAdapter, ProviderSettingsUIHookInput, ProviderSettingsUIHookResult } from \"../../core/provider-settings-ui-contract.js\";\nimport {\n GITHUB_IDENTITY_PROVIDER_ID,\n DEFAULT_BOT_IDENTITY_CONFIG,\n type CreateGitHubAppManifestResult,\n type ConvertGitHubAppManifestResult,\n type GetGitHubAppManifestFlowResult,\n type BotIdentitySettingsEntry,\n type PaperclipAgentOption,\n} from \"../../shared/types.js\";\nimport {\n errorStyle,\n fieldStyle,\n fieldsetStyle,\n formActionsStyle,\n formatSecretOption,\n getFallbackTokenSecretFieldHint,\n getSecretFieldHint,\n hintStyle,\n inlineNoticeStyle,\n inputStyle,\n legendStyle,\n linkStyle,\n manifestPanelStyle,\n secondaryButtonStyle,\n successStyle,\n} from \"../../ui/SettingsPage.js\";\n\n// The GitHub analogue of ./slack/settings-adapter-ui.tsx (see that module's\n// header comment for the overall pattern this mirrors). GitHub's credential\n// step previously lived inline in src/ui/SettingsPage.tsx, branching on\n// config.provider === \"github\" -- the same architectural gap Copilot flagged\n// against #63/#74 for Slack. Moving it here closes that gap for both\n// providers: SettingsPage no longer owns any provider-specific manifest\n// state, effects, or handlers, only the shared wizard chrome.\n//\n// Deliberately NOT importing from \"./index.js\" (the github provider's\n// server-side composition, which pulls in app-manifest.ts's `node:crypto`\n// usage) -- this module is client code (JSX/hooks are fine to import here,\n// unlike settings-adapter.ts), but it must still avoid pulling server-only\n// code into the client Settings UI bundle.\n\nexport interface GitHubSettingsUIFormConfig {\n agentId: string;\n provider: string;\n label: string;\n previousAgentId: string;\n githubUsername: string;\n commitName: string;\n commitEmail: string;\n githubAppId: string;\n githubInstallationId: string;\n privateKeySecretId: string;\n privateKeyFile: string;\n fallbackTokenSecretId: string;\n tokenFile: string;\n previousGithubAppId: string;\n previousGithubInstallationId: string;\n previousPrivateKeySecretId: string;\n previousPrivateKeyFile: string;\n [key: string]: string;\n}\n\nexport interface GitHubSettingsUIHookResult extends ProviderSettingsUIHookResult {\n manifestFlow: CreateGitHubAppManifestResult | null;\n manifestBusy: boolean;\n manifestCode: string;\n setManifestCode: (value: string) => void;\n manifestError: string | null;\n manifestResult: ConvertGitHubAppManifestResult | null;\n handleCreateGitHubAppManifest: () => Promise<void>;\n handleConvertGitHubAppManifest: () => Promise<void>;\n updateField: (field: keyof GitHubSettingsUIFormConfig & string, value: string) => void;\n secretOptions: ReadonlyArray<{ id: string; name: string; key?: string; description?: string; provider?: string; status?: string }>;\n secretsLoading: boolean;\n secretsError: string | null;\n companyId: string;\n}\n\nconst MANIFEST_DRAFT_STORAGE_PREFIX = \"paperclip-agent-identities:github-app-manifest-draft:\";\n\nfunction getManifestDraftStorageKey(state: string): string {\n return MANIFEST_DRAFT_STORAGE_PREFIX + state;\n}\n\nfunction writeManifestDraftForm(state: string, formState: GitHubSettingsUIFormConfig): void {\n try {\n window.sessionStorage.setItem(getManifestDraftStorageKey(state), JSON.stringify(formState));\n } catch {\n // Redirect restoration is best-effort; the server-side manifest flow still restores required fields.\n }\n}\n\nfunction readManifestDraftForm(state: string): Partial<GitHubSettingsUIFormConfig> | null {\n try {\n const raw = window.sessionStorage.getItem(getManifestDraftStorageKey(state));\n if (!raw) return null;\n return normalizeManifestDraftForm(JSON.parse(raw));\n } catch {\n return null;\n }\n}\n\nfunction deleteManifestDraftForm(state: string): void {\n try {\n window.sessionStorage.removeItem(getManifestDraftStorageKey(state));\n } catch {\n // Ignore sessionStorage cleanup failures; stale drafts are scoped by opaque manifest state.\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction readString(value: unknown): string {\n return typeof value === \"string\" ? value : \"\";\n}\n\nfunction normalizeManifestDraftForm(raw: unknown): Partial<GitHubSettingsUIFormConfig> | null {\n if (!isRecord(raw)) return null;\n return {\n agentId: readString(raw.agentId),\n provider: readString(raw.provider) || GITHUB_IDENTITY_PROVIDER_ID,\n label: readString(raw.label),\n githubUsername: readString(raw.githubUsername),\n commitName: readString(raw.commitName),\n commitEmail: readString(raw.commitEmail),\n githubAppId: readString(raw.githubAppId),\n githubInstallationId: readString(raw.githubInstallationId),\n privateKeySecretId: readString(raw.privateKeySecretId),\n privateKeyFile: readString(raw.privateKeyFile),\n fallbackTokenSecretId: readString(raw.fallbackTokenSecretId),\n tokenFile: readString(raw.tokenFile),\n previousAgentId: readString(raw.previousAgentId),\n previousGithubAppId: readString(raw.previousGithubAppId),\n previousGithubInstallationId: readString(raw.previousGithubInstallationId),\n previousPrivateKeySecretId: readString(raw.previousPrivateKeySecretId),\n previousPrivateKeyFile: readString(raw.previousPrivateKeyFile),\n };\n}\n\nfunction submitGitHubAppManifest(flow: CreateGitHubAppManifestResult) {\n const form = document.createElement(\"form\");\n form.method = \"post\";\n form.action = flow.postUrl;\n form.target = \"_blank\";\n form.setAttribute(\"rel\", \"noopener noreferrer\");\n const manifest = document.createElement(\"input\");\n manifest.type = \"hidden\";\n manifest.name = \"manifest\";\n manifest.value = flow.manifest;\n form.appendChild(manifest);\n document.body.appendChild(form);\n form.submit();\n form.remove();\n}\n\nfunction getManifestReturnUrl(): string {\n const url = new URL(window.location.href);\n url.searchParams.delete(\"code\");\n url.searchParams.delete(\"installation_id\");\n url.searchParams.delete(\"setup_action\");\n url.searchParams.delete(\"state\");\n url.searchParams.set(\"githubAppManifest\", \"1\");\n return url.toString();\n}\n\nfunction getAgentDashboardUrl(agentId: string): string {\n const url = new URL(window.location.href);\n const companySegment = url.pathname.split(\"/\").filter(Boolean)[0];\n const agentSegment = encodeURIComponent(agentId);\n url.pathname = companySegment\n ? `/${encodeURIComponent(companySegment)}/agents/${agentSegment}/dashboard`\n : `/agents/${agentSegment}/dashboard`;\n url.search = \"\";\n url.hash = \"\";\n return url.toString();\n}\n\nexport function getManifestCallbackParams(): { code?: string; installationId?: string; state: string } | null {\n const url = new URL(window.location.href);\n const code = url.searchParams.get(\"code\")?.trim();\n const installationId = url.searchParams.get(\"installation_id\")?.trim();\n const state = url.searchParams.get(\"state\")?.trim();\n if (!state?.startsWith(\"pc_\") || (!code && !installationId)) return null;\n return { ...(code ? { code } : {}), ...(installationId ? { installationId } : {}), state };\n}\n\nfunction cleanManifestCallbackParams() {\n const url = new URL(window.location.href);\n url.searchParams.delete(\"code\");\n url.searchParams.delete(\"installation_id\");\n url.searchParams.delete(\"setup_action\");\n url.searchParams.delete(\"state\");\n url.searchParams.delete(\"githubAppManifest\");\n window.history.replaceState(window.history.state, document.title, url.toString());\n}\n\nexport function extractManifestCode(value: string): string {\n const trimmed = value.trim();\n if (!trimmed) return \"\";\n\n try {\n const parsed = new URL(trimmed);\n return parsed.searchParams.get(\"code\")?.trim() || trimmed;\n } catch {\n return trimmed.replace(/^code=/i, \"\").trim();\n }\n}\n\n// GitHub's credential step needs its own dedicated worker actions\n// (create/get/convert-github-app-manifest), obtained via `usePluginAction`\n// -- which must be called at a component's top level, not lazily here.\n// SettingsPage calls usePluginAction for these itself and threads the\n// resulting callables through the hook input, mirroring Slack's\n// SlackSettingsUIActionsInput.\nexport interface GitHubSettingsUIActionsInput {\n createGitHubAppManifest: (input: Record<string, unknown>) => Promise<unknown>;\n getGitHubAppManifestFlow: (input: Record<string, unknown>) => Promise<unknown>;\n convertGitHubAppManifest: (input: Record<string, unknown>) => Promise<unknown>;\n // GitHub's redirect-restore effect needs to resolve saved-identity and\n // agent-default values, unlike Slack's simpler sessionStorage-only\n // restore -- these are read-only inputs SettingsPage already computes.\n identities: readonly BotIdentitySettingsEntry[];\n agentOptions: readonly PaperclipAgentOption[];\n companyDisplayName: string;\n credentialSidecarPath: string;\n getAgentIdentityDefaults: (\n agent: PaperclipAgentOption,\n companyDisplayName: string,\n credentialSidecarPath: string,\n ) => { label: string; githubUsername: string; commitName: string; commitEmail: string; privateKeyFile: string };\n toFormState: (entry?: BotIdentitySettingsEntry) => GitHubSettingsUIFormConfig;\n}\n\ntype GitHubCredentialStepInput = ProviderSettingsUIHookInput<GitHubSettingsUIFormConfig> & GitHubSettingsUIActionsInput;\n\nfunction useGitHubCredentialStep(input: GitHubCredentialStepInput): GitHubSettingsUIHookResult {\n const {\n config,\n updateField,\n createGitHubAppManifest,\n getGitHubAppManifestFlow,\n convertGitHubAppManifest,\n identities,\n agentOptions,\n companyDisplayName,\n credentialSidecarPath,\n getAgentIdentityDefaults,\n toFormState,\n patchFormState,\n } = input;\n\n const [manifestFlow, setManifestFlow] = useState<CreateGitHubAppManifestResult | null>(null);\n const [manifestBusy, setManifestBusy] = useState(false);\n const [manifestCode, setManifestCode] = useState(\"\");\n const [manifestError, setManifestError] = useState<string | null>(null);\n const [manifestResult, setManifestResult] = useState<ConvertGitHubAppManifestResult | null>(null);\n\n function reset() {\n setManifestFlow(null);\n setManifestCode(\"\");\n setManifestError(null);\n setManifestResult(null);\n }\n\n // Restore an in-progress GitHub App manifest flow after GitHub redirects\n // back to the callback URL with ?code=/&installation_id=&state=. Unlike\n // Slack (which has no redirect callback and relies on sessionStorage\n // alone), GitHub's flow is driven by the URL the browser lands on after\n // leaving the page entirely, so this runs once on mount rather than\n // being generation-guarded the way Slack's local-state resets are.\n useEffect(() => {\n const callback = getManifestCallbackParams();\n if (!callback) return;\n\n let cancelled = false;\n setManifestBusy(true);\n setManifestError(null);\n setManifestResult(null);\n void getGitHubAppManifestFlow({ state: callback.state })\n .then((result) => {\n if (cancelled) return;\n const flow = result as GetGitHubAppManifestFlowResult;\n const savedIdentity = identities.find((entry) => entry.agentId === flow.agentId && entry.provider === flow.provider);\n const selectedAgent = agentOptions.find((agent) => agent.id === flow.agentId);\n const defaults = selectedAgent\n ? getAgentIdentityDefaults(selectedAgent, companyDisplayName, credentialSidecarPath)\n : null;\n const restoredForm = toFormState(savedIdentity);\n const draftForm = readManifestDraftForm(callback.state);\n const conversion = flow.conversion;\n patchFormState(() => ({\n ...restoredForm,\n ...draftForm,\n agentId: flow.agentId,\n provider: flow.provider,\n label: draftForm?.label || restoredForm.label || flow.label,\n githubUsername: conversion?.githubUsername || draftForm?.githubUsername || restoredForm.githubUsername || defaults?.githubUsername || DEFAULT_BOT_IDENTITY_CONFIG.github.username,\n commitName: draftForm?.commitName || restoredForm.commitName || defaults?.commitName || \"\",\n commitEmail: draftForm?.commitEmail || restoredForm.commitEmail || defaults?.commitEmail || \"\",\n githubAppId: conversion?.appId || draftForm?.githubAppId || restoredForm.githubAppId,\n githubInstallationId: callback.installationId || restoredForm.githubInstallationId,\n privateKeyFile: conversion?.privateKeyFile || draftForm?.privateKeyFile || restoredForm.privateKeyFile || defaults?.privateKeyFile || \"\",\n }));\n setManifestFlow(flow);\n setManifestCode(callback.code ?? \"\");\n if (callback.installationId) {\n setManifestResult(conversion ?? null);\n deleteManifestDraftForm(callback.state);\n void getGitHubAppManifestFlow({ state: callback.state, consume: true }).catch(() => undefined);\n }\n cleanManifestCallbackParams();\n })\n .catch((err) => {\n if (!cancelled) {\n setManifestError(err instanceof Error ? err.message : \"Could not restore GitHub App manifest flow\");\n }\n })\n .finally(() => {\n if (!cancelled) {\n setManifestBusy(false);\n }\n });\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agentOptions, companyDisplayName, credentialSidecarPath, getGitHubAppManifestFlow, identities]);\n\n async function handleCreateGitHubAppManifest() {\n if (!config) return;\n if (config.provider !== GITHUB_IDENTITY_PROVIDER_ID) {\n setManifestError(\"GitHub App setup is only available for the GitHub provider.\");\n return;\n }\n setManifestBusy(true);\n setManifestError(null);\n setManifestResult(null);\n try {\n const result = await createGitHubAppManifest({\n agentId: config.agentId.trim(),\n provider: config.provider,\n label: config.label.trim(),\n homepageUrl: getAgentDashboardUrl(config.agentId.trim()),\n callbackUrl: getManifestReturnUrl(),\n }) as CreateGitHubAppManifestResult;\n setManifestFlow(result);\n writeManifestDraftForm(result.state, config);\n submitGitHubAppManifest(result);\n } catch (err) {\n setManifestError(err instanceof Error ? err.message : \"Failed to create GitHub App manifest\");\n } finally {\n setManifestBusy(false);\n }\n }\n\n async function handleConvertGitHubAppManifest() {\n if (!manifestFlow || !config) return;\n setManifestBusy(true);\n setManifestError(null);\n try {\n const result = await convertGitHubAppManifest({\n state: manifestFlow.state,\n code: manifestCode.trim(),\n }) as ConvertGitHubAppManifestResult;\n const nextFormState = {\n ...config,\n githubAppId: result.appId,\n privateKeyFile: result.privateKeyFile,\n githubUsername: result.githubUsername,\n };\n writeManifestDraftForm(manifestFlow.state, nextFormState);\n setManifestResult(result);\n updateField(\"githubAppId\", result.appId);\n updateField(\"privateKeyFile\", result.privateKeyFile);\n updateField(\"githubUsername\", result.githubUsername);\n window.location.assign(result.installUrl);\n } catch (err) {\n setManifestError(err instanceof Error ? err.message : \"Failed to convert GitHub App manifest\");\n } finally {\n setManifestBusy(false);\n }\n }\n\n return {\n validationExtra: {},\n reset,\n manifestFlow,\n manifestBusy,\n manifestCode,\n setManifestCode,\n manifestError,\n manifestResult,\n handleCreateGitHubAppManifest,\n handleConvertGitHubAppManifest,\n updateField,\n secretOptions: input.secretOptions,\n secretsLoading: input.secretsLoading,\n secretsError: input.secretsError,\n companyId: input.companyId,\n };\n}\n\nfunction GitHubAppManifestCreateIntro() {\n return (\n <div style={inlineNoticeStyle}>\n <strong>Create a GitHub App with a manifest.</strong> This opens GitHub with the required app permissions prefilled. After GitHub creates the app, Paperclip saves the generated private key file, preloads the App ID, opens the install flow, and restores the form with the Installation ID when GitHub redirects back.\n </div>\n );\n}\n\nfunction GitHubAppManifestActions(props: {\n manifestBusy: boolean;\n disabled: boolean;\n manifestFlow: CreateGitHubAppManifestResult | null;\n onCreate: () => void;\n buttonLabel: string;\n}) {\n return (\n <div style={formActionsStyle}>\n <button\n type=\"button\"\n onClick={props.onCreate}\n disabled={props.manifestBusy || props.disabled}\n style={secondaryButtonStyle}\n >\n {props.manifestBusy ? \"Working...\" : props.buttonLabel}\n </button>\n {props.manifestFlow && <span style={hintStyle}>Manifest ready for {props.manifestFlow.appName}. GitHub should be open in a new tab.</span>}\n </div>\n );\n}\n\nfunction GitHubCredentialStep(props: { state: GitHubSettingsUIHookResult; config: GitHubSettingsUIFormConfig }) {\n const { state, config } = props;\n const { manifestFlow, manifestBusy, manifestCode, setManifestCode, manifestError, manifestResult, handleCreateGitHubAppManifest, handleConvertGitHubAppManifest } = state;\n const hasExistingGitHubAppCredential = Boolean(\n config.previousGithubAppId ||\n config.previousGithubInstallationId ||\n config.previousPrivateKeySecretId ||\n config.previousPrivateKeyFile\n );\n const hasSecretOptions = state.secretOptions.length > 0;\n const hasSavedSecretOutsideOptions = Boolean(\n config.privateKeySecretId && !state.secretOptions.some((secret) => secret.id === config.privateKeySecretId)\n );\n const hasSavedFallbackSecretOutsideOptions = Boolean(\n config.fallbackTokenSecretId && !state.secretOptions.some((secret) => secret.id === config.fallbackTokenSecretId)\n );\n\n return (\n <fieldset style={fieldsetStyle}>\n <legend style={legendStyle}>GitHub App credential source</legend>\n\n {hasExistingGitHubAppCredential ? (\n <div style={inlineNoticeStyle}>\n <strong>GitHub App already configured.</strong> Edit the fields below to update the saved App ID, Installation ID, or private key source. Creating another manifest is a replacement/rotation flow; it creates a new GitHub App and does not update the existing app in GitHub.\n </div>\n ) : (\n <GitHubAppManifestCreateIntro />\n )}\n\n {hasExistingGitHubAppCredential ? (\n <details>\n <summary>Replace this GitHub App with a new manifest-created app</summary>\n <div style={{ display: \"grid\", gap: \"0.75rem\", marginTop: \"0.75rem\" }}>\n <GitHubAppManifestCreateIntro />\n <GitHubAppManifestActions\n manifestBusy={manifestBusy}\n disabled={!config.agentId || !config.label}\n manifestFlow={manifestFlow}\n onCreate={() => void handleCreateGitHubAppManifest()}\n buttonLabel=\"Create replacement GitHub App on GitHub\"\n />\n </div>\n </details>\n ) : (\n <GitHubAppManifestActions\n manifestBusy={manifestBusy}\n disabled={!config.agentId || !config.label}\n manifestFlow={manifestFlow}\n onCreate={() => void handleCreateGitHubAppManifest()}\n buttonLabel=\"Create GitHub App on GitHub\"\n />\n )}\n\n {manifestFlow && (\n <div style={manifestPanelStyle}>\n <div style={fieldStyle}>\n <span style={hintStyle}>If a popup was blocked, use this manual form:</span>\n <form action={manifestFlow.postUrl} method=\"post\" target=\"_blank\">\n <input type=\"hidden\" name=\"manifest\" value={manifestFlow.manifest} />\n <button type=\"submit\" style={secondaryButtonStyle}>Open GitHub manifest form</button>\n </form>\n </div>\n <label style={fieldStyle}>\n <span>Callback code</span>\n <input\n type=\"text\"\n value={manifestCode}\n onChange={(e) => setManifestCode(extractManifestCode(e.target.value))}\n placeholder=\"Paste GitHub's callback URL or just the code=... value\"\n style={inputStyle}\n />\n </label>\n <div style={formActionsStyle}>\n <button\n type=\"button\"\n onClick={() => void handleConvertGitHubAppManifest()}\n disabled={manifestBusy || !manifestCode.trim()}\n style={secondaryButtonStyle}\n >\n Save generated private key and prefill fields\n </button>\n {manifestResult && <a href={manifestResult.installUrl} target=\"_blank\" rel=\"noreferrer\" style={linkStyle}>Install GitHub App</a>}\n </div>\n </div>\n )}\n\n {manifestError && <span style={errorStyle}>{manifestError}</span>}\n {manifestResult && config.githubInstallationId ? (\n <span style={successStyle}>GitHub App {manifestResult.appName} installed. Review the prefilled Installation ID, then save this identity.</span>\n ) : manifestResult ? (\n <span style={successStyle}>GitHub App {manifestResult.appName} created. Install it on GitHub; Paperclip will prefill the Installation ID when GitHub redirects back.</span>\n ) : null}\n\n {hasExistingGitHubAppCredential && (\n <div style={formActionsStyle}>\n <a href=\"https://github.com/settings/apps\" target=\"_blank\" rel=\"noreferrer\" style={linkStyle}>Manage GitHub Apps</a>\n <a href=\"https://github.com/settings/installations\" target=\"_blank\" rel=\"noreferrer\" style={linkStyle}>Manage GitHub App installations</a>\n </div>\n )}\n\n <label style={fieldStyle}>\n <span>GitHub App ID</span>\n <input\n type=\"text\"\n value={config.githubAppId}\n onChange={(e) => state.updateField(\"githubAppId\", e.target.value)}\n placeholder=\"GitHub App ID\"\n style={inputStyle}\n />\n </label>\n\n <label style={fieldStyle}>\n <span>Installation ID</span>\n <input\n type=\"text\"\n value={config.githubInstallationId}\n onChange={(e) => state.updateField(\"githubInstallationId\", e.target.value)}\n placeholder=\"GitHub App installation ID\"\n style={inputStyle}\n />\n </label>\n\n <label style={fieldStyle}>\n <span>Private key Paperclip secret UUID</span>\n {hasSecretOptions ? (\n <select\n value={config.privateKeySecretId}\n onChange={(e) => state.updateField(\"privateKeySecretId\", e.target.value)}\n style={inputStyle}\n >\n <option value=\"\">No private key secret reference</option>\n {hasSavedSecretOutsideOptions && <option value={config.privateKeySecretId}>{config.privateKeySecretId} (saved)</option>}\n {state.secretOptions.map((secret) => (\n <option key={secret.id} value={secret.id}>{formatSecretOption(secret)}</option>\n ))}\n </select>\n ) : (\n <input\n type=\"text\"\n value={config.privateKeySecretId}\n onChange={(e) => state.updateField(\"privateKeySecretId\", e.target.value)}\n placeholder=\"Company secret UUID containing the GitHub App private key\"\n style={inputStyle}\n />\n )}\n <span style={hintStyle}>{getSecretFieldHint({ companyId: state.companyId, secretsLoading: state.secretsLoading, secretsError: state.secretsError, hasSecretOptions })}</span>\n </label>\n\n <label style={fieldStyle}>\n <span>Private key file fallback</span>\n <input\n type=\"text\"\n value={config.privateKeyFile}\n onChange={(e) => state.updateField(\"privateKeyFile\", e.target.value)}\n placeholder=\"<runtime-home>/.paperclip/agent-identities/github-apps/<agent>/private-key.pem\"\n style={inputStyle}\n />\n <span style={hintStyle}>Used by plugin tools while a secret UUID is not configured or cannot be resolved. The plugin mints short-lived installation tokens from this private key; it does not store generated tokens.</span>\n </label>\n\n <details>\n <summary>Fallback token source</summary>\n <div style={{ display: \"grid\", gap: \"0.75rem\", marginTop: \"0.75rem\" }}>\n <label style={fieldStyle}>\n <span>Fallback token secret UUID</span>\n {hasSecretOptions ? (\n <select\n value={config.fallbackTokenSecretId}\n onChange={(e) => state.updateField(\"fallbackTokenSecretId\", e.target.value)}\n style={inputStyle}\n >\n <option value=\"\">No fallback token secret reference</option>\n {hasSavedFallbackSecretOutsideOptions && <option value={config.fallbackTokenSecretId}>{config.fallbackTokenSecretId} (saved)</option>}\n {state.secretOptions.map((secret) => (\n <option key={secret.id} value={secret.id}>{formatSecretOption(secret)}</option>\n ))}\n </select>\n ) : (\n <input\n type=\"text\"\n value={config.fallbackTokenSecretId}\n onChange={(e) => state.updateField(\"fallbackTokenSecretId\", e.target.value)}\n placeholder=\"Company secret UUID containing a GitHub token\"\n style={inputStyle}\n />\n )}\n <span style={hintStyle}>{getFallbackTokenSecretFieldHint({ companyId: state.companyId, secretsLoading: state.secretsLoading, secretsError: state.secretsError, hasSecretOptions })}</span>\n </label>\n <label style={fieldStyle}>\n <span>Fallback token file</span>\n <input\n type=\"text\"\n value={config.tokenFile}\n onChange={(e) => state.updateField(\"tokenFile\", e.target.value)}\n placeholder=\"<runtime-home>/.paperclip/agent-identities/tokens/<agent-id>.token\"\n style={inputStyle}\n />\n <span style={hintStyle}>Fallback token files are available for dev and recovery flows. Prefer GitHub App credentials above.</span>\n </label>\n </div>\n </details>\n </fieldset>\n );\n}\n\nexport const githubSettingsUIAdapter: ProviderSettingsUIAdapter<GitHubSettingsUIFormConfig, GitHubSettingsUIHookResult, GitHubCredentialStepInput> = {\n providerId: GITHUB_IDENTITY_PROVIDER_ID,\n useCredentialStep: useGitHubCredentialStep,\n CredentialStep: GitHubCredentialStep,\n getRemovalConfirmation(entry) {\n return `Delete agent identity mapping for ${entry.label}? This clears the saved GitHub App binding for this agent; the GitHub App itself and its installation are not deleted, only unlinked from this agent. To reconnect later, create a new GitHub mapping with \"Add identity\".`;\n },\n};\n", "// The Settings-UI-rendering analogue of `settings-index.ts`. Deliberately a\n// SEPARATE module for the same reason as settings-index.ts: this is imported\n// by the client Settings UI bundle, so it must only depend on per-provider\n// `settings-adapter-ui.tsx` modules (client-safe, may import React/JSX), not\n// on server-only provider composition (app-manifest.ts's `node:crypto` usage,\n// credential resolution touching the filesystem).\n//\n// Adding a settings-capable provider's UI = add its `settings-adapter-ui.tsx`\n// module and append it to ALL_SETTINGS_UI_ADAPTERS here.\nimport { buildProviderSettingsUIRegistry } from \"../core/provider-settings-ui-contract.js\";\nimport { slackSettingsUIAdapter } from \"./slack/settings-adapter-ui.js\";\nimport { githubSettingsUIAdapter } from \"./github/settings-adapter-ui.js\";\n\nexport const ALL_SETTINGS_UI_ADAPTERS = [githubSettingsUIAdapter, slackSettingsUIAdapter] as const;\n\nexport const providerSettingsUIRegistry = buildProviderSettingsUIRegistry([...ALL_SETTINGS_UI_ADAPTERS]);\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["usePluginData", "useEffect", "useState", "hasFallbackCredential", "useEffect", "useState", "useState", "useEffect", "useEffect", "useState", "jsx", "jsxs", "getAgentIdentityDefaults", "toFormState", "useState", "useEffect", "formatSecretOption", "getSecretFieldHint", "jsx", "jsxs", "useState", "useEffect", "formatSecretOption", "getSecretFieldHint", "isRecord", "readString", "nextEnv", "jsx", "jsxs", "usePluginData", "toneBackground"]
|
|
7
|
+
}
|