* 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>
Tools with requiresConfirmation (e.g. user_table) blocked indefinitely
in mothership because the frontend has no approval UI. Added a new
promptForToolApproval orchestrator option so mothership auto-executes
these tools while copilot continues to prompt for user approval.
Made-with: Cursor
Co-authored-by: Theodore Li <theo@sim.ai>
* Fix deploy subagent
* fix(stream) handle task switching (#3609)
* Fix task switching causing stream to abort
* Process all task streams all the time
* Process task streams that are in the background
---------
Co-authored-by: Theodore Li <theo@sim.ai>
* Always return isDeployed for undeploy chat
* Fix lint
---------
Co-authored-by: Siddharth Ganesan <siddharthganesan@gmail.com>
Co-authored-by: Theodore Li <theo@sim.ai>
* fix(deploy): consolidate deployment detection into single source of truth
* fix(deploy): address PR review feedback
- Remove redundant isLoading check (subset of isPending in RQ v5)
- Make deployedState prop nullable to avoid non-null assertion
- Destructure mutateAsync to eliminate ESLint suppression
- Guard debounced invalidation against stale workflowId on switch
* fix(deploy): clean up self-explanatory comments and fix unstable mutation dep
- Remove self-explanatory comments in deploy.tsx, tool-input.tsx, use-child-workflow.ts
- Tighten non-obvious comments in use-change-detection.ts
- Destructure mutate/isPending in WorkflowToolDeployBadge to avoid unstable
mutation object in useCallback deps (TanStack Query no-unstable-deps pattern)
* lint
* fix(deploy): skip expensive state merge when deployedState is null
Avoid running mergeSubblockStateWithValues on every render for
non-deployed workflows where changeDetected always returns false.
* fix(deploy): add missing workflow table import in deploy route
Pre-existing type error — workflow table was used but not imported.
* fix(deploy): forward AbortSignal in fetchDeployedWorkflowState
Match the pattern used by all other fetch helpers in the file so
in-flight requests are cancelled on component unmount or query re-trigger.
* perf(deploy): parallelize all DB queries in checkNeedsRedeployment
All three queries (active version, normalized data, workflow variables)
now run concurrently via Promise.all, saving one DB round trip on the
common path.
* fix(deploy): use sequential-then-parallel pattern in checkNeedsRedeployment
* fix(deploy): use client-side comparison for editor header, remove server polling
The lastSaved-based server polling was triggering API calls on every
local store mutation (before socket persistence), wasting requests and
checking stale DB state. Revert the editor header to pure client-side
hasWorkflowChanged comparison — zero network during editing, instant
badge updates. Child workflow badges still use server-side
useDeploymentInfo (they don't have Zustand state).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(deploy): suppress transient Update flash during deployed state refetch
Guard change detection on isFetching (not just isLoading) so the
comparison is suppressed during background refetches after mutations,
preventing a brief Update→Live badge flicker.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* improvement(connectors): audit and harden all 30 knowledge base connectors
* fix(oauth): update Notion test to match Basic Auth + JSON body config
* fix(connectors): address PR review comments for hubspot, jira, salesforce
- HubSpot: revert to Search API (POST /search) to restore lastmodifieddate DESCENDING sorting
- Salesforce: restore ArticleBody field and add it to HTML_FIELDS for proper stripping
- Jira: add zero-remaining guard to prevent requesting 0 maxResults
* fix(salesforce): revert ArticleBody — not a standard KnowledgeArticleVersion field
ArticleBody is not a standard field on KnowledgeArticleVersion per Salesforce
API docs. Article body content lives in custom fields on org-specific __kav
objects. Including ArticleBody in the SOQL query would cause runtime errors.
* fix(connectors): address second round of PR review comments
- OneDrive: use Buffer.subarray for byte-accurate truncation instead of
character-count slice
- Reddit: deduplicate comment extraction — fetchPostComments now calls
extractComments instead of duplicating the logic
- Webflow: replace crude value.includes('<') with regex /<[a-z][^>]*>/i
to avoid false positives on plain text containing '<'
- Jira: add response.ok check in getJiraCloudId before parsing JSON to
surface real HTTP errors instead of misleading "No Jira resources found"
* fix(jira,outlook): replace raw fetch in downloadJiraAttachments, fix Outlook URL encoding
- Jira: replace bare fetch() with fetchWithRetry in downloadJiraAttachments
for retry logic on transient errors and rate limits
- Outlook: use URLSearchParams in validateConfig $search URL construction
to match buildInitialUrl and produce RFC 3986 compliant encoding