* fix(oauth): decode ID token instead of calling Graph API for Microsoft providers
* fix(oauth): fix type error in getMicrosoftUserInfoFromIdToken parameter
* fix(oauth): address review comments - try-catch JSON.parse, fix email fallback order, guard undefined email
* style(oauth): format email fallback chain to single line
* feat(slack): add conversations.create and conversations.invite tools
* fix(slack): address PR review comments on conversation tools
* feat(slack): wire create/invite conversation tools into Slack block
* lint
* fix(slack): rename channel output to channelInfo to avoid type collision
The block outputs already declare `channel` as type string (channel ID from
send operation). Rename the object output to `channelInfo` to match the
pattern used by get_channel_info and avoid [object Object] rendering.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(slack): update output key in docs to match channelInfo rename
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(docs): fix lint errors in auto-generated docs files
Sort imports in icon-mapping.ts and add trailing newline to meta.json.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* lint
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
h-0 w-0 overflow-hidden was clipping the iframe, preventing
Turnstile from executing. absolute takes it out of flow without
clipping, fixing both the layout gap and the captcha failure.
* v0
* Fix ppt load
* Fixes
* Fixes
* Fix lint
* Fix wid
* Download image
* Update tools
* Fix lint
* Fix error msg
* Tool fixes
* Reenable subagent stream
* Subagent stream
* Fix edit workflow hydration
* Throw func execute error on error
* Sandbox PPTX generation in subprocess with vm.createContext
AI-generated PptxGenJS code was executed via new Function() in both
the server (full Node.js access) and browser (XSS risk). Replace with
a dedicated Node.js subprocess (pptx-worker.cjs) that runs user code
inside vm.createContext with a null-prototype sandbox — no access to
process, require, Buffer, or any Node.js globals. Process-level
isolation ensures a vm escape cannot reach the main process or DB.
File access is brokered via IPC so the subprocess never touches the
database directly, mirroring the isolated-vm worker pattern. Compilation
happens lazily at serve time (compilePptxIfNeeded) rather than on write,
matching industry practice for source-stored PPTX pipelines.
- Add pptx-worker.cjs: sandboxed subprocess worker
- Add pptx-vm.ts: orchestration, IPC bridge, file brokering
- Add /api/workspaces/[id]/pptx/preview: REST-correct preview endpoint
- Update serve route: compile pptxgenjs source to binary on demand
- Update workspace-file.ts: remove unsafe new Function(), store source only
- Update next.config.ts: include pptxgenjs in outputFileTracingIncludes
- Update trigger.config.ts: add pptx-worker.cjs and pptxgenjs to build
* upgrade deps, file viewer
* Fix auth bypass, SSRF, and wrong size limit comment
- Add 'patch' to workspace_file WRITE_ACTIONS — patch operation was
missing, letting read-only users modify file content
- Add download_to_workspace_file to WRITE_ACTIONS with '*' wildcard —
tool was completely ungated, letting read-only users write workspace files
- Update isActionAllowed to handle '*' (always-write tools) and undefined
action (tools with no operation/action field)
- Block private/internal URLs in download_to_workspace_file to prevent
SSRF against RFC 1918 ranges, loopback, and cloud metadata endpoints
- Fix file-reader.ts image size limit comment and error message (was 20MB,
actual constant is 5MB)
* Fix Buffer not assignable to BodyInit in preview route
Wrap Buffer in Uint8Array for NextResponse body — Buffer is not
directly assignable to BodyInit in strict TypeScript mode.
* Fix SSRF bypass, IPv6 coverage, download size cap, and missing deps
- Validate post-redirect URL to block SSRF via open redirectors
- Expand IPv6 private range blocking: fe80::/10, fc00::/7, ::ffff: mapped
- Add 50 MB download cap (Content-Length pre-check + post-buffer check)
- Add refetchOnWindowFocus: 'always' to useWorkspaceFileBinary
- Add workspaceId to PptxPreview useEffect dependency array
* Replace hand-rolled SSRF guard with secureFetchWithValidation
The previous implementation hand-rolled private-IP detection with regex,
missing edge cases (octal IPs, hex IPs, full IPv6 coverage). The codebase
already has secureFetchWithValidation which uses ipaddr.js, handles DNS
rebinding via IP pinning, validates each redirect target, and enforces a
streaming size cap — removing the need for isPrivateUrl, isPrivateIPv4,
the manual pre/post-redirect checks, and the Content-Length + post-buffer
size checks.
* Fix streaming preview cache ordering and patch ambiguity
- PptxPreview: move streaming content check before cache check so live
AI-generated previews are never blocked by a warm cache from a prior
file view
- workspace_file patch: reject edits where the search string matches
more than one location, preventing silent wrong-location patches
- workspace_file patch: remove redundant Record<string, unknown> cast;
args is already Zod-validated with the correct field types
* Fix subprocess env leak, unbounded preview spawning, and dead code
- pptx-vm: pass minimal env to worker subprocess so it cannot inherit
DB URLs, API keys, or other secrets from the Next.js process on a
vm.createContext escape
- PptxPreview: add AbortController so in-flight preview fetch is
cancelled when the effect re-runs (e.g. next SSE update), preventing
unbounded concurrent subprocesses; add 500ms debounce on streaming
renders to reduce subprocess churn during rapid AI generation
- file-reader: remove dead code — the `if (!isReadableType)` guard on
line 110 was always true (all readable types returned earlier at
line 76), making the subsequent `return null` unreachable
* Wire abort signal through to subprocess and correct security comment
- generatePptxFromCode now accepts an optional AbortSignal; when the
signal fires (e.g. client disconnects mid-stream), done() is called
which clears timers and kills the subprocess immediately rather than
waiting for the 60s timeout
- preview route passes req.signal so client-side AbortController.abort()
(from the streaming debounce cleanup) propagates all the way to the
worker process
- Correct misleading comment in pptx-worker.cjs and pptx-vm.ts:
vm.createContext is NOT a sandbox when non-primitives are in scope;
the real security boundary is the subprocess + minimal env
* Remove implementation-specific comments from pptx worker files
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix pre-aborted signal, pptx-worker tracing, and binary fetch cache
* Lazy worker path resolution, code size cap, unused param prefix
* Add cache-busting timestamp to binary file fetch
* Fix PPTX cache key stability and attribute-order-independent dimension parsing
* ran lint
---------
Co-authored-by: waleed <walif6@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(sidebar): add right-click context menu to settings nav item
* fix(sidebar): revert settings active highlight
* fix(sidebar): allow modifier-key clicks to open in new tab, make InfisicalIcon black
* update icons
* fix(kb): store filename with .txt extension for connector documents
Connector documents (e.g. Fireflies transcripts) have titles without
file extensions. The DB stored the raw title as filename, but the
processing pipeline extracts file extension from filename to determine
the parser. On retry/reprocess, this caused "Unsupported file type"
errors with the document title treated as the extension.
Now stores processingFilename (which includes .txt) instead of the
raw title, consistent with what was actually uploaded to storage.
* fix(kb): guard stuck document retry against filenames without extension
Existing DB rows may have connector document filenames stored without
a .txt extension (raw meeting titles). The stuck-doc retry path reads
filename from DB and passes it to parseHttpFile, which extracts the
extension via split('.'). When there's no dot, the entire title
becomes the "extension", causing "Unsupported file type" errors.
Falls back to 'document.txt' when the stored filename has no extension.
* fix(kb): fix race condition in stuck document retry during sync
The stuck document retry at the end of each sync was querying for all
documents with processingStatus 'pending' or 'failed'. This included
documents added in the CURRENT sync that were still processing
asynchronously, causing duplicate concurrent processing attempts.
The race between the original (correct) processing and the retry
(which reads the raw title from DB as filename) produced
nondeterministic failures — some documents would succeed while
others would fail with "Unsupported file type: <meeting title>".
Fixes:
- Filter stuck doc query by uploadedAt < syncStartedAt to exclude
documents from the current sync
- Pass mimeType through to parseHttpFile so text/plain content can
be decoded directly without requiring a file extension in the
filename (matches parseDataURI which already handles this)
- Restore filename as extDoc.title in DB (the display name, not
the processing filename)
* fix(kb): fix race condition in stuck document retry during sync
The stuck document retry at the end of each sync was querying for all
documents with processingStatus 'pending' or 'failed'. This included
documents added in the CURRENT sync that were still processing
asynchronously, causing duplicate concurrent processing attempts.
The race between the original (correct) processing and the retry
(which reads the raw title from DB as filename) produced
nondeterministic failures — some documents would succeed while
others would fail with "Unsupported file type: <meeting title>".
Fixes:
- Filter stuck doc query by uploadedAt < syncStartedAt to exclude
documents from the current sync
- Pass mimeType through to parseHttpFile and use existing
getExtensionFromMimeType utility as fallback when filename has
no extension (e.g. Fireflies meeting titles)
- Apply same mimeType fallback in parseDataURI for consistency
* lint
* fix(kb): handle empty extension edge case in parseDataURI
When filename ends with a dot (e.g. "file."), split('.').pop() returns
an empty string. Fall through to mimeType-based extension lookup
instead of passing empty string to parseBuffer.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(turnstile): conditionally added CF turnstile to signup
* feat(auth): add execute-on-submit Turnstile, conditional harmony, and feature flag
- Switch Turnstile to execution: 'execute' mode so challenge runs on
form submit (fresh token every time, no expiry issues)
- Make emailHarmony conditional via SIGNUP_EMAIL_VALIDATION_ENABLED
feature flag so self-hosted users can opt out
- Add isSignupEmailValidationEnabled to feature-flags.ts following
existing pattern
- Add better-auth-harmony to Next.js transpilePackages (required for
validator.js ESM compatibility)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor(validation): remove dead validateEmail and checkMXRecord
Server-side disposable email blocking is now handled by
better-auth-harmony. The async validateEmail (with MX check) had no
remaining callers. Only quickValidateEmail remains for client-side
form feedback.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(auth): add 15s timeout to Turnstile captcha promise
Prevents form from hanging indefinitely if Turnstile never fires
onSuccess/onError (e.g. script fails to load, network drop).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore(helm): add Turnstile and harmony env vars to values.yaml
Adds TURNSTILE_SECRET_KEY, NEXT_PUBLIC_TURNSTILE_SITE_KEY, and
SIGNUP_EMAIL_VALIDATION_ENABLED to the helm chart so self-hosted
deployments can configure captcha and disposable email blocking.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(auth): reject captcha promise on token expiry
onExpire now rejects the pending promise so the form doesn't hang
if the Turnstile token expires mid-challenge.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor(login): replace useEffect keydown listener with form onSubmit
The forgot-password modal used a global window keydown listener in a
useEffect to handle Enter key — a "you might not need an effect"
anti-pattern with a stale closure risk. Replaced with a native
<form onSubmit> wrapper which handles Enter natively, eliminating
the useEffect, the global listener, and the stale closure.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(auth): clear dangling timeout after captcha promise settles
Use .finally(() => clearTimeout(timeoutId)) to clean up the 15s
timeout timer when the captcha resolves before the deadline.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor(auth): use getResponsePromise() for Turnstile token retrieval
Replace the manual Promise + refs + timeout pattern with the
documented getResponsePromise(timeout) API from @marsidev/react-turnstile.
This eliminates captchaToken state, captchaResolveRef, captchaRejectRef,
and all callback wiring on the Turnstile component.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(auth): show captcha errors as form-level message, not password error
Captcha failures were misleadingly displayed under the password field.
Added a dedicated formError state that renders above the submit button,
making it clear the issue is with verification, not the password.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* 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