* chore(templates): disable templates page and related UI
* chore(templates): remove unused imports from disabled template code
* fix(config): restore noNestedComponentDefinitions rule in biome config
* chore(templates): comment out remaining dead template code
Comment out handleTemplateFormSubmit, handleTemplateDelete,
TemplateStatusBadge component, and TemplateProfile dynamic import
that were left over after disabling the templates feature.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore(templates): clean up dead code from review feedback
- Remove unused usePathname/pathnameRef in use-workspace-management.ts
- Comment out stale 'template' from TabView union type
- Remove unused params from TemplateLayoutProps interface
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(preview): show actual nested workflow name in log snapshots
* fix(preview): ensure metadata.name in non-deployed child workflow path
* style(preview): fix line formatting
* fix(landing): update broken links, change colors
* update integration pages
* update icons
* link to tag
* fix(landing): resolve build errors and address PR review comments
- Extract useEffect redirect into ExternalRedirect client component to fix
fs/promises bundling error in privacy/terms server pages
- Fix InfisicalIcon fill='black' → fill='currentColor' for theme compatibility
- Add target="_blank" + rel="noopener noreferrer" to enterprise Typeform link
- Install @types/micromatch to fix missing type declarations build error
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(icons): fix InfisicalIcon fill='black' → fill='currentColor' in docs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* remove hardcoded ff
* fix(generate-docs): fix tool description extraction for two-step and name-mismatch patterns
Replace the fragile first-id/first-description heuristic with a per-id
window search: for each id: 'tool_id' match, scan the next 600 chars
(stopping before any params: block) for description: and name: fields.
This correctly handles the two-step pattern used by Intercom and others
where the ToolConfig export comes after a separate base object whose
params: would have cut off the old approach.
Add an exact-name fallback that checks tools.access for a tool whose
name matches the operation label — handles cases where block op IDs are
short aliases (e.g. Slack 'send') while the tool ID is more descriptive
('slack_message') but the tool name 'Slack Message' still differs.
Remove the word-overlap scoring fallback which was producing incorrect
descriptions (Intercom all saying 'Intercom API access token', Reddit
Save/Unsave inverted, etc.).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(okta): add complete Okta identity management integration
Add 18 Okta Management API tools covering user lifecycle (list, get,
create, update, activate, deactivate, suspend, unsuspend, reset password,
delete) and group management (list, get, create, update, delete, add/remove
members, list members). Includes block with conditional UI, icon, registry
entries, and generated docs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(okta): add manual description section to generated docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(okta): address PR review — SSRF prevention, safe response parsing, consistent sendEmail
- Add validateOktaDomain() to prevent SSRF via user-supplied domain param
- Fix 9 tools to check response.ok before calling response.json()
- Make sendEmail query param explicit in deactivate_user and delete_user
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(okta): only forward boolean switches when explicitly true
Switch subBlocks default to OFF (false), which was being forwarded to
tools and overriding their default-true behavior for sendEmail and
activate params. Now only forward these when explicitly toggled ON.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(okta): use nullish coalescing for boolean switch defaults
Block now forwards sendEmail/activate values as-is (including false).
Tools use ?? operator so: explicit true/false from switches are respected,
undefined (programmatic calls) still defaults to true.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(okta): prevent silent data loss in update operations
- update_group: always include description in PUT body (defaults to '')
since PUT replaces the full profile object
- update_user: use !== undefined checks so empty strings can clear fields
via Okta's POST partial update
- block: allow empty strings through passthrough loop and use !== undefined
for groupDescription mapping
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(okta): move validateOktaDomain to centralized input-validation
- Moved validateOktaDomain from tools/okta/types.ts to
lib/core/security/input-validation.ts alongside other validation utils
- Added .trim() to handle copy-paste whitespace in domain input
- Updated all 18 tool files to import from the new location
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(microsoft-ad): add Azure AD (Entra ID) integration
Add complete Azure AD integration with 13 tools for managing users
and groups via Microsoft Graph API v1.0. Includes OAuth config with
PKCE, block definition with conditional subBlocks, and generated docs.
Tools: list/get/create/update/delete users, list/get/create/update/delete
groups, list/add/remove group members.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(microsoft-ad): add $search/$filter guard, $count=true, and memberId validation
- Prevent using $search and $filter together (Graph API rejects this)
- Add $count=true when $search is used (required with ConsistencyLevel: eventual)
- Validate and trim memberId in add_group_member body before use
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(microsoft-ad): fix docsLink underscore and accountEnabled update safety
- Change docsLink from microsoft-ad to microsoft_ad to match docs routing
- Split accountEnabled dropdown into separate create/update subBlocks
- Update operation shows "No Change" default (empty string) to prevent
silently re-enabling disabled accounts when updating other fields
- Create operation keeps "Yes" default as before
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(microsoft-ad): prevent visibility from always being sent on group update
Split visibility dropdown into separate create/update subBlocks with
"No Change" default for update_group, preventing silent overwrite of
group visibility when updating other fields like description.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(microsoft-ad): prevent empty values leaking into PATCH requests
- Use operation-aware checks for accountEnabled and visibility in block
params to prevent create defaults bleeding into update operations
- Change tool body guards from `!== undefined` to truthy checks so
empty-string inputs from unfilled subBlocks are omitted from PATCH
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* improvement(react): replace unnecessary useEffect patterns with better React primitives
* fix(react): revert unsafe render-time side effects to useEffect
* fix(react): restore useEffect for modals, scroll, and env sync
- Modals (create-workspace, rename-document, edit-knowledge-base): restore
useEffect watching `open` prop for form reset on programmatic open, since
Radix onOpenChange doesn't fire for parent-driven prop changes
- Popover: add useEffect watching `open` for programmatic close reset
- Chat scroll: restore useEffect watching `isStreamingResponse` so the 1s
suppression timer starts when streaming begins, not before the fetch
- Credentials manager: revert render-time pattern to useEffect for initial
sync from cached React Query data (useRef captures initial value, making
the !== check always false on mount)
* fix(react): restore useEffect for help/invite modals, combobox index reset
- Help modal: restore useEffect watching `open` for form reset on
programmatic open (same Radix onOpenChange pattern as other modals)
- Invite modal: restore useEffect watching `open` to clear error on
programmatic open
- Combobox: restore useEffect to reset highlightedIndex when filtered
options shrink (prevents stale index from reappearing when options grow)
- Remove no-op handleOpenChange wrappers in rename-document and
edit-knowledge-base modals (now pure pass-throughs after useEffect fix)
* fix(context-menu): use requestAnimationFrame for ColorGrid focus, remove no-op wrapper in create-workspace-modal
- ColorGrid: replaced setTimeout with requestAnimationFrame for initial
focus to wait for submenu paint completion
- create-workspace-modal: removed handleOpenChange pass-through wrapper,
use onOpenChange directly
* fix(files): restore filesRef pattern to prevent preview mode reset on refetch
The useEffect that sets previewMode should only run when selectedFileId
changes, not when files array reference changes from React Query refetch.
Restores the filesRef pattern to read latest files without triggering
the effect — prevents overriding user's manual mode selection.
* fix(add-documents-modal, combobox): restore useEffect for modal reset, fix combobox dep array
- add-documents-modal: handleOpenChange(true) is dead code in Radix
controlled mode — restored useEffect watching open for reset-on-open
- combobox: depend on filteredOptions array (not .length) so highlight
resets when items change even with same count
Providers like Box don't return a scope field in their token response,
leaving the account.scope column empty. The credentials API now falls
back to the provider's configured scopes when the stored scope is
empty, preventing false "Additional permissions required" banners.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(box): add Box and Box Sign integrations
Add complete Box integration with file management (upload, download, get info, list folders, create/delete folders, copy, search, update metadata) and Box Sign e-signature support (create/get/list/cancel/resend sign requests). Includes OAuth provider setup, internal upload API route following the Dropbox pattern, block configurations, icon, and generated docs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(box): address PR review comments
- Fix docsLink for Box Sign: use underscore (box_sign) to match docs URL
- Move normalizeFileInput from tool() to params() in Box block config to match Dropbox pattern
- Throw error on invalid additionalSigners JSON instead of silently dropping signers
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(box): remove unsupported reason param from cancel sign request
The Box Sign cancel endpoint (POST /sign_requests/{id}/cancel) does not
accept a request body per the API specification. Remove the misleading
reason parameter from the tool, types, block config, and docs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(box): use canonical param ID for file normalization in params()
The params function must reference canonical IDs (params.file), not raw
subBlock IDs (uploadFile/fileRef) which are deleted after canonical
transformation. Matches the Dropbox block pattern.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(box): use generic output descriptions for shared file properties
Rename "Uploaded file ID/name" to "File ID/name" in
UPLOAD_FILE_OUTPUT_PROPERTIES since the constant is shared by both
upload and copy operations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(box): rename items output to entries for list_folder_items
Rename the output field from "items" to "entries" to match Box API
naming and avoid collision with JSON schema "items" keyword that
prevented the docs generator from rendering the nested array structure.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(box): filter empty file IDs from sourceFileIds input
Add .filter(Boolean) after splitting sourceFileIds to prevent empty
strings from trailing/double commas being sent as invalid file IDs
to the Box Sign API.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(box): merge Box Sign into single Box block
Combine Box and Box Sign into one unified block with all 15 operations
accessible via a single dropdown, removing the separate box_sign block.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(box): filter empty strings from tags array in update_file
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* style(docs): apply lint formatting to icon-mapping and meta.json
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* style(box): format chained method calls per linter rules
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* style(box,docusign): set block bgColor to white and regenerate docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* style(docs): apply lint formatting
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(box): populate OAuth scopes for Box since token response omits them
Box's OAuth2 token endpoint does not return a scope field in the
response, so Better Auth stores nothing in the DB. This causes the
credential selector to always show "Additional permissions required".
Fix by populating the scope from the requested scopes in the
account.create.before hook.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(box): add sign_requests.readwrite scope for Box Sign operations
Box Sign API requires the sign_requests.readwrite scope in addition
to root_readwrite. Without it, sign requests fail with "The request
requires higher privileges than provided by the access token."
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* update docs
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(ashby): add 15 new tools and fix existing tool accuracy
* fix(ashby): fix response field mappings for changeStage and createNote
* fix(ashby): fix websiteUrl field name in candidate.update request
* fix(ashby): revert body field names to candidateId and jobId for info endpoints
* fix(ashby): add subblock ID migrations for removed emailType and phoneType
* fix(ashby): map removed emailType/phoneType to dummy keys to avoid data corruption
* feat(docusign): add DocuSign e-signature integration
* fix(docusign): add base_uri null check and move file normalization to params
* fix(docusign): use canonical param documentFile instead of raw subBlock IDs
* fix(docusign): validate document file is present before sending envelope
* fix(docusign): rename tool files from kebab-case to snake_case for docs generation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(knowledge): infer MIME type from file extension in create/upsert tools
Both create_document and upsert_document forced .txt extension and
text/plain MIME type regardless of the document name. Now the tools
infer the correct MIME type from the file extension (html, md, csv,
json, yaml, xml) and only default to .txt when no extension is given.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(knowledge): reuse existing getMimeTypeFromExtension from uploads
Replace duplicate EXTENSION_MIME_MAP and getMimeTypeFromExtension with
the existing, more comprehensive version from lib/uploads/utils/file-utils.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(knowledge): fix btoa stack overflow and duplicate encoding in create_document
Same fixes as upsert_document: use loop-based String.fromCharCode
instead of spread, consolidate duplicate TextEncoder calls, and
check byte length instead of character length for 1MB limit.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(knowledge): allowlist text-compatible MIME types in inferDocumentFileInfo
Use an explicit allowlist instead of only checking for octet-stream,
preventing binary MIME types (image/jpeg, audio/mpeg, etc.) from
leaking through when a user names a document with a binary extension.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(knowledge): remove pdf/rtf from allowlist, normalize unrecognized extensions
- Remove application/pdf and application/rtf from TEXT_COMPATIBLE_MIME_TYPES
since these tools pass plain text content, not binary
- Normalize unrecognized extensions (e.g. report.v2) to .txt instead of
preserving the original extension with text/plain MIME type
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(knowledge): handle dotfile names to avoid empty base in filename
Dotfiles like .env would produce an empty base, resulting in '.txt'.
Now falls back to the original name so .env becomes .env.txt.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* chore(blog): add v0.6 blog post and email broadcast scaffolding
* mothership blog
* turned on mothership blog
* small change
---------
Co-authored-by: Emir Karabeg <emirkarabeg@berkeley.edu>
* feat(home): resizable chat/resource panel divider
* fix(home): address PR review comments
- Remove aria-hidden from resize handle outer div so separator role is visible to AT
- Add viewport-resize re-clamping in useMothershipResize to prevent panel exceeding max % after browser window narrows
- Change default MothershipView width from 60% to 50%
* refactor(home): eradicate useEffect anti-patterns per you-might-not-need-an-effect
- use-chat: remove messageQueue→ref sync Effect; inline assignment like other refs
- use-chat: replace activeResourceId selection Effect with useMemo (derived value, avoids
extra re-render cycle; activeResourceIdRef now tracks effective value for API payloads)
- use-chat: replace 3x useLayoutEffect ref-sync (processSSEStream, finalize, sendMessage)
with direct render-phase assignment — consistent with existing resourcesRef pattern
- user-input: fold onEditValueConsumed callback into existing render-phase guard; remove Effect
- home: move isResourceAnimatingIn 400ms timer into expandResource/handleResourceEvent event
handlers where setIsResourceAnimatingIn(true) is called; remove reactive Effect watcher
* fix(home): revert default width to 60%, reduce max resize to 63%
* improvement(react): replace useEffect anti-patterns with better React primitives
* improvement(react): replace useEffect anti-patterns with better React primitives
* improvement(home): use pointer events for resize handle (touch + mouse support)
* fix(autosave): store idle-reset timer ref to prevent status corruption on rapid saves
* fix(home): move onEditValueConsumed call out of render phase into useEffect
* fix(home): add pointercancel handler; fix(settings): sync name on profile refetch
* fix(home): restore cleanupRef assignment dropped during AbortController refactor
* improvement(landing): added enterprise section
* make components interactive
* added more things to pricing sheet
* remove debug log
* fix(landing): remove dead DotGrid component and fix enterprise CTA to use Link
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(knowledge): add upsert document operation to Knowledge block
Add a "Create or Update" (upsert) document capability that finds an
existing document by ID or filename, deletes it if found, then creates
a new document and queues re-processing. Includes new tool, API route,
block wiring, and typed interfaces.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(knowledge): address review comments on upsert document
- Reorder create-then-delete to prevent data loss if creation fails
- Move Zod validation before workflow authorization for validated input
- Fix btoa stack overflow for large content using loop-based encoding
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(knowledge): guard against empty createDocumentRecords result
Add safety check before accessing firstDocument to prevent TypeError
and data loss if createDocumentRecords unexpectedly returns empty.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(knowledge): prevent documentId fallthrough and use byte-count limit
- Use if/else so filename lookup only runs when no documentId is provided,
preventing stale IDs from silently replacing unrelated documents
- Check utf8 byte length instead of character count for 1MB size limit,
correctly handling multi-byte characters (CJK, emoji)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(knowledge): rollback on delete failure, deduplicate sub-block IDs
- Add compensating rollback: if deleteDocument throws after create
succeeds, clean up the new record to prevent orphaned pending docs
- Merge duplicate name/content sub-blocks into single entries with
array conditions, matching the documentTags pattern
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* lint
* lint
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(admin): add user search by email and ID, remove table border
- Replace Load Users button with a live search input; query fires on any input
- Email search uses listUsers with contains operator
- User ID search (UUID format) uses admin.getUser directly for exact lookup
- Remove outer border on user table that rendered white in dark mode
- Reset pagination to page 0 on new search
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(admin): replace live search with explicit search button
- Split searchInput (controlled input) from searchQuery (committed value)
so the hook only fires on Search click or Enter, not every keystroke
- Gate table render on searchQuery.length > 0 to prevent stale results
showing after input is cleared
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(logs): persist execution diagnostics markers
Store last-started and last-completed block markers with finalization metadata so later read surfaces can explain how a run ended without reconstructing executor state.
* fix(executor): preserve durable diagnostics ordering
Await only the persistence needed to keep diagnostics durable before terminal completion while keeping callback failures from changing execution behavior.
* fix(logs): preserve fallback diagnostics semantics
Keep successful fallback output and accumulated cost intact while tightening progress-write draining and deduplicating trace span counting for diagnostics helpers.
* fix(api): restore async execute route test mock
Add the missing AuthType export to the hybrid auth mock so the async execution route test exercises the 202 queueing path instead of crashing with a 500 in CI.
* fix(executor): align async block error handling
* fix(logs): tighten marker ordering scope
Allow same-millisecond marker writes to replace prior markers and drop the unused diagnostics read helper so this PR stays focused on persistence rather than unread foundation code.
* fix(logs): remove unused finalization type guard
Drop the unused helper so this PR only ships the persistence-side status types it actually uses.
* fix(executor): await subflow diagnostics callbacks
Ensure empty-subflow and subflow-error lifecycle callbacks participate in progress-write draining before terminal finalization while still swallowing callback failures.
---------
Co-authored-by: test <test@example.com>
Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai>
* feat(csp): allow chat UI to be embedded in iframes
Mirror the existing form embed CSP pattern for chat pages: add
getChatEmbedCSPPolicy() with frame-ancestors *, configure /chat/:path*
headers in next.config.ts without X-Frame-Options, and early-return in
proxy.ts so chat routes skip the strict runtime CSP.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(csp): extract shared getEmbedCSPPolicy helper
Deduplicate getChatEmbedCSPPolicy and getFormEmbedCSPPolicy into a
shared private helper to prevent future divergence.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(auth): migrate to better-auth admin plugin
* feat(settings): add unified Admin tab with user management
Consolidate superuser features into a single Admin settings tab:
- Super admin mode toggle (moved from General)
- Workflow import (moved from Debug)
- User management via better-auth admin (list, set role, ban/unban)
Replace Debug tab with Admin tab gated by requiresAdminRole.
Add React Query hooks for admin user operations.
* fix(db): backfill existing super users to admin role in migration
Add UPDATE statement to promote is_super_user=true rows to role='admin'
before dropping the is_super_user column, preventing silent demotion.
* fix(admin): resolve type errors in admin tab
- Fix cn import path to @/lib/core/utils/cn
- Use valid Badge variants (blue/gray/red/green instead of secondary/destructive)
- Type setRole param as 'user' | 'admin' union
* improvement(auth): remove /api/user/super-user route, use session role
Include user.role in customSession so it's available client-side.
Replace all useSuperUserStatus() calls with session.user.role === 'admin'.
Delete the now-redundant /api/user/super-user endpoint.
* chore(auth): remove redundant role override in customSession
The admin plugin already includes role on the user object.
No need to manually spread it in customSession.
* improvement(queries): clean up admin-users hooks per React Query best practices
- Remove unsafe unknown/Record casting, use better-auth typed response
- Add placeholderData: keepPreviousData for paginated variable-key query
- Remove nullable types where defaults are always applied
* fix(admin): address review feedback on admin tab
- Fix superUserModeEnabled default to false (matches sidebar behavior)
- Reset banReason when switching ban target to prevent state bleed
- Guard admin section render with session role check for direct URL access
* fix(settings): align superUserModeEnabled default to false everywhere
Three places defaulted to true while admin tab and sidebar used false.
Align all to false so new admins see consistent behavior.
* fix(admin): fix stale pendingUserId, add isPending guard and error feedback
- Only read mutation.variables when mutation isPending (prevents stale ID)
- Add isPending guard to super user mode toggle (prevents concurrent mutations)
- Show inline error message when setRole/ban/unban mutations fail
* fix(admin): concurrent pending users Set, session loading guard, domain blocking
- Replace pendingUserId scalar with pendingUserIds Set (useMemo) so concurrent
mutations across different users each disable their own row correctly
- Add sessionLoading guard to admin section redirect to prevent flash on direct
/settings/admin navigation before session resolves
- Add BLOCKED_SIGNUP_DOMAINS env var and before-hook for email domain denylist,
parsed once at module init as a Set for O(1) per-request lookups
- Add trailing newline to migration file
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(admin): close OAuth domain bypass, fix stale errors, deduplicate icon
- Add databaseHooks.user.create.before to enforce BLOCKED_SIGNUP_DOMAINS at
the model level, covering all signup vectors (email, OAuth, social) not just
/sign-up paths
- Call .reset() on each mutation before firing to clear stale error state from
previous operations
- Change Admin nav icon from ShieldCheck to Lock to avoid duplicate with
Access Control tab
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* improvement(mothership): tool display titles, html sanitization, and ui fixes
- Use TOOL_UI_METADATA as fallback for tool display titles (fast_edit shows "Editing workflow" instead of "Fast Edit")
- Harden HTML-to-text extraction with replaceUntilStable to prevent nested tag injection
- Decode HTML entities in a single pass to avoid double-unescaping
- Fix Google Drive/Docs query escaping for backslashes in folder IDs
- Replace regex with indexOf for email sender/display name parsing
- Update embedded workflow run tooltip to "Run workflow"
* fix(security): decode entities before tag stripping and cap loop iterations
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Include notification view in embedded workflow view
* fix(ui) fix workflow not showing up when mothership calls run
* Wire up fix in mothership
* Refresh events after workflow run
* Fix so run workflow switches tabs as well
---------
Co-authored-by: Theodore Li <theo@sim.ai>