- Add max-w-[260px] to Tooltip.Content so video previews don't blow out the tooltip size
- Replace cursor-help with cursor-default on info icons in settings
* improvement(tour): fix tour auto-start logic and standardize selectors
* fix(tour): address PR review comments
- Move autoStartAttempted.add() inside timer callback to prevent
blocking auto-start when tour first mounts while disabled
- Memoize setJoyrideRef with useCallback to prevent ref churn
- Remove unused joyrideRef
* feat(home): auth-aware landing page navigation
- Redirect authenticated users from / to /workspace via middleware (?home param bypasses)
- Show "Go to App" instead of "Log in / Get started" in navbar for authenticated users
- Logo links to /?home for authenticated users to stay in marketing context
- Settings "Home Page" button opens /?home
- Handle isPending session state to prevent CTA button flash
* lint
* fix(home): remove stale ?from=nav params in landing nav
* fix(home): preserve ?home param in nav links during session pending state
* lint
* feat: add product tour
* chore: updated modals
* chore: fix the tour
* chore: Tour Updates
* chore: fix review changes
* chore: fix review changes
* chore: fix review changes
* chore: fix review changes
* chore: fix review changes
* minor improvements
* chore(tour): address PR review comments
- Extract shared TourState, TourStateContext, mapPlacement, and TourTooltipAdapter
into tour-shared.tsx, eliminating ~100 lines of duplication between product-tour.tsx
and workflow-tour.tsx
- Fix stale closure in handleStartTour — add isOnWorkflowPage to useCallback deps
so Take a tour dispatches the correct event after navigation
* chore(tour): address remaining PR review comments
- Remove unused logger import and instance in product-tour.tsx
- Remove unused tour-tooltip-fade animation from tailwind config
- Remove unnecessary overflow-hidden wrapper around WorkflowTour
- Add border stroke to arrow SVG in tour-tooltip for visual consistency
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore(tour): address second round of PR review comments
- Remove unnecessary 'use client' from workflow layout (children are already client components)
- Fix ref guard timing issue in TourTooltipAdapter that could prevent Joyride from tracking tooltip on subsequent steps
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore(tour): extract shared Joyride config, fix popover arrow overflow
- Extract duplicated Joyride floaterProps/styles into getSharedJoyrideProps()
in tour-shared.tsx, parameterized by spotlightBorderRadius
- Fix showArrow disabling content scrolling in PopoverContent by wrapping
children in a scrollable div when arrow is visible
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* lint
* fix(tour): stop running tour when disabled becomes true
Prevents nav and workflow tours from overlapping. When a user navigates
to a workflow page while the nav tour is running, the disabled flag
now stops the nav tour instead of just suppressing auto-start.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(tour): move auto-start flag into timer, fix truncate selector conflict
- Move hasAutoStarted flag inside setTimeout callback so it's only set
when the timer fires, allowing retry if disabled changes during delay
- Add data-popover-scroll attribute to showArrow scroll wrapper and
exclude it from the flex-1 truncate selector to prevent overflow
conflict
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(tour): remove duplicate overlay on center-placed tour steps
Joyride's spotlight already renders a full-screen overlay via boxShadow.
The centered TourTooltip was adding its own bg-black/55 overlay on top,
causing double-darkened backgrounds. Removed the redundant overlay div.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: move docs link from settings to help dropdown
The Docs link (https://docs.sim.ai) was buried in settings navigation.
Moved it to the Help dropdown in the sidebar for better discoverability.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Adithya Krishna <aadithya794@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(table): column drag-and-drop reorder
* fix(table): remove duplicate onDragEnd call from handleDrop
* fix(table): persist columnOrder on rename/delete and defer delete to onSuccess
* fix(table): prevent stale refs during column drag operations
Fix two bugs in column drag-and-drop:
1. Stale columnWidths ref during rename - compute updated widths inline
before passing to updateMetadata
2. Escape-cancelled drag still reorders - update dropTargetColumnNameRef
directly in handleColumnDragLeave to prevent handleColumnDragEnd from
reading stale ref value
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(table): insert column at correct side when anchor is unordered
When the anchor column isn't in columnOrder, add it first then insert
the new column relative to it, so 'right' insertions appear after the
anchor as expected.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(home): voice input text persistence bugs
* fix(home): gate setIsListening on startRecognition success
* fix(home): handle startRecognition failure in restartRecognition
* fix(home): reset speech prefix on submit while mic is active
* 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>