Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: simstudioai/sim
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: ca87d7c
Choose a base ref
...
head repository: simstudioai/sim
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: e615816
Choose a head ref
  • 16 commits
  • 650 files changed
  • 6 contributors

Commits on Mar 26, 2026

  1. Configuration menu
    Copy the full SHA
    3597eac View commit details
    Browse the repository at this point in the history
  2. fix(landing): fix image rendering and navbar blog/docs navigation (#3785

    )
    
    * fix(landing): fix image rendering and navbar blog/docs navigation
    
    * fix(navbar): remove disclosure aria attributes from navigation links
    waleedlatif1 authored Mar 26, 2026
    Configuration menu
    Copy the full SHA
    3774f33 View commit details
    Browse the repository at this point in the history
  3. fix: emcn component library design engineering polish (#3672)

    * chore: fix conflicts
    
    * chore: fix conflicts
    
    * chore: pause marquee
    
    * chore: fix conflicts
    
    * chore: fix conflicts
    
    * chore: address review comments
    
    * chore: fix conflicts
    
    * chore: other bug fixes
    
    * chore: fix conflicts
    
    * chore: fix radius
    
    * chore: fix review changes
    
    * chore: fix conflicts
    
    * chore: revert other
    
    * chore: fix conflicts
    
    * chore: fix review changes
    
    * chore: fix conflicts
    
    * chore: fix review changes
    
    * chore: fix button state
    
    * chore: fix button state
    
    * chore: fix review changes
    
    * chore: fix lint
    
    * chore: fix conflicts
    
    * chore: add metadata
    
    * chore: fix things
    
    * chore: fix overwritten states
    
    * chore: fix warnings
    
    * chore: fix button state
    
    * chore: fix review changes
    
    * chore: fix review changes
    
    * chore: fix hover state
    
    * chore: fix popover
    
    * chore: fix review changes
    
    * chore: fix review changes
    adithyaakrishna authored Mar 26, 2026
    Configuration menu
    Copy the full SHA
    5aa0b4d View commit details
    Browse the repository at this point in the history
  4. feat: fix rerenders on search input (#3784)

    * chore: fix conflicts
    
    * chore: update contents
    
    * chore: fix review changes
    adithyaakrishna authored Mar 26, 2026
    Configuration menu
    Copy the full SHA
    bc4b7f5 View commit details
    Browse the repository at this point in the history
  5. chore(config): clean up bun, turbo, and next.js config (#3788)

    * chore(config): clean up bun, turbo, and next.js config
    
    * chore(ci): bump bun to 1.3.11 in dockerfiles and workflows
    waleedlatif1 authored Mar 26, 2026
    Configuration menu
    Copy the full SHA
    8a481b6 View commit details
    Browse the repository at this point in the history
  6. chore: fix cn with tw-merge (#3789)

    * chore: fix cn
    
    * chore: fix scale
    adithyaakrishna authored Mar 26, 2026
    Configuration menu
    Copy the full SHA
    bf60670 View commit details
    Browse the repository at this point in the history
  7. feat(granola): add Granola meeting notes integration (#3790)

    * feat(granola): add Granola meeting notes integration
    
    * fix(granola): use string comparison for includeTranscript to avoid truthy string bug
    
    * fix(granola): add missing get_note output fields to block definition
    
    * regen docs
    waleedlatif1 authored Mar 26, 2026
    Configuration menu
    Copy the full SHA
    7a1a460 View commit details
    Browse the repository at this point in the history
  8. feat(ketch): add Ketch privacy consent integration (#3794)

    * feat(ketch): add Ketch privacy consent integration
    
    * fix(ketch): add response.ok guards and fix registry ordering
    
    * fix(ketch): include errorMessage in error response output for all tools
    
    * fix(ketch): wire optional purposes filter for get_consent operation
    waleedlatif1 authored Mar 26, 2026
    Configuration menu
    Copy the full SHA
    f37e4b6 View commit details
    Browse the repository at this point in the history
  9. fix(security): harden auth, SSRF, injection, and CORS across API rout…

    …es (#3792)
    
    * fix: prevent auth bypass via user-controlled context query param in file serve
    
    The /api/files/serve endpoint trusted a user-supplied `context` query
    parameter to skip authentication. An attacker could append
    `?context=profile-pictures` to any file URL and download files without
    auth. Now the public access gate checks the key prefix instead of the
    query param, and `og-images/` is added to `inferContextFromKey`.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix: use randomized heredoc delimiter in SSH execute-script route
    
    Prevents accidental heredoc termination if script content contains
    the delimiter string on its own line.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix: escape workingDirectory in SSH execute-command route
    
    Use escapeShellArg() with single quotes for the workingDirectory
    parameter, consistent with all other SSH routes (execute-script,
    create-directory, delete-file, move-rename).
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix: harden chat/form deployment auth (OTP brute-force, CSPRNG, HMAC tokens)
    
    - Add brute-force protection to OTP verification with attempt tracking (CWE-307)
    - Replace Math.random() with crypto.randomInt() for OTP generation (CWE-338)
    - Replace unsigned Base64 auth tokens with HMAC-SHA256 signed tokens (CWE-327)
    - Use shared isEmailAllowed utility in OTP route instead of inline duplicate
    - Simplify Redis OTP update to single KEEPTTL call
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix: harden SSRF protections and input validation across API routes
    
    Add DNS-based SSRF validation for MCP server URLs, secure OIDC discovery
    with IP-pinned fetch, strengthen OTP/chat/form input validation, sanitize
    1Password vault parameters, and tighten deployment security checks.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * lint
    
    * fix(file-serve): remove user-controlled context param from authenticated path
    
    The `?context` query param was still being passed to `handleCloudProxy`
    in the authenticated code path, allowing any logged-in user to spoof
    context as `profile-pictures` and bypass ownership checks in
    `verifyFileAccess`. Now always use `inferContextFromKey` from the
    server-controlled key prefix.
    
    * fix: handle legacy OTP format in decodeOTPValue for deploy-time compat
    
    Add guard for OTP values without colon separator (pre-deploy format)
    to avoid misparse that would lock out users with in-flight OTPs.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix(mcp): distinguish DNS resolution failures from SSRF policy blocks
    
    DNS lookup failures now throw McpDnsResolutionError (502) instead of
    McpSsrfError (403), so transient DNS hiccups surface as retryable
    upstream errors rather than confusing permission rejections.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix: make OTP attempt counting atomic to prevent TOCTOU race
    
    Redis path: use Lua script for atomic read-increment-conditional-delete.
    DB path: use optimistic locking (UPDATE WHERE value = currentValue) with
    re-read fallback on conflict. Prevents concurrent wrong guesses from
    each counting as a single attempt.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix: check attempt count before OTP comparison to prevent bypass
    
    Reject OTPs that have already reached max failed attempts before
    comparing the code, closing a race window where a correct guess
    could bypass brute-force protection.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix: validate OIDC discovered endpoints against SSRF
    
    The discovery URL itself was SSRF-validated, but endpoint URLs returned
    in the discovery document (tokenEndpoint, userInfoEndpoint, jwksEndpoint)
    were stored without validation. A malicious OIDC issuer on a public IP
    could return internal network URLs in the discovery response.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix: remove duplicate OIDC endpoint SSRF validation block
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix: validate OIDC discovered endpoints and pin DNS for 1Password Connect
    
    - SSRF-validate all endpoint URLs returned by OIDC discovery documents
      before storing them (authorization, token, userinfo, jwks endpoints)
    - Pin DNS resolution in 1Password Connect requests using
      secureFetchWithPinnedIP to prevent TOCTOU DNS rebinding attacks
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * lint
    
    * fix: replace KEEPTTL with TTL+EX for Redis <6.0 compat, add DB retry loop
    
    - Lua script now reads TTL and uses SET...EX instead of KEEPTTL
    - DB optimistic locking now retries up to 3 times on conflict
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix: address review feedback on OTP atomicity and 1Password fetch
    
    - Replace Redis KEEPTTL with TTL+SET EX for Redis <6.0 compatibility
    - Add retry loop to DB optimistic lock path so concurrent OTP attempts
      are actually counted instead of silently dropped
    - Remove unreachable fallback fetch in 1Password Connect; make
      validateConnectServerUrl return non-nullable string
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix: treat Lua nil return as locked when OTP key is missing
    
    When the Redis key is deleted/expired between getOTP and
    incrementOTPAttempts, the Lua script returns nil. Handle this
    as 'locked' instead of silently treating it as 'incremented'.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix: handle Lua nil as locked OTP and add SSRF check to MCP env resolution
    
    - Treat Redis Lua nil return (expired/deleted key) as 'locked' instead
      of silently treating it as a successful increment
    - Add validateMcpServerSsrf to MCP service resolveConfigEnvVars so
      env-var URLs are SSRF-validated after resolution at execution time
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix: narrow resolvedIP type guard instead of non-null assertion
    
    Replace urlValidation.resolvedIP! with proper type narrowing by adding
    !urlValidation.resolvedIP to the guard clause, so TypeScript can infer
    the string type without a fragile assertion.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix: bind auth tokens to deployment password for immediate revocation
    
    Include a SHA-256 hash of the encrypted password in the HMAC-signed
    token payload. Changing the deployment password now immediately
    invalidates all existing auth cookies, restoring the pre-HMAC behavior.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix: bind auth tokens to deployment password and remove resolvedIP non-null assertion
    
    - Include SHA-256 hash of encryptedPassword in HMAC token payload so
      changing a deployment's password immediately invalidates all sessions
    - Pass encryptedPassword through setChatAuthCookie/setFormAuthCookie
      and validateAuthToken at all call sites
    - Replace non-null assertion on resolvedIP with proper narrowing guard
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix: update test assertions for new encryptedPassword parameter
    
    Tests now expect the encryptedPassword arg passed to validateAuthToken
    and setDeploymentAuthCookie after the password-binding change.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix: format long lines in chat/form test assertions
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix: pass encryptedPassword through OTP route cookie generation
    
    Select chat.password in PUT handler DB query and pass it to
    setChatAuthCookie so OTP-issued tokens include the correct
    password slot for subsequent validation.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    ---------
    
    Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
    waleedlatif1 and claude authored Mar 26, 2026
    Configuration menu
    Copy the full SHA
    66ce673 View commit details
    Browse the repository at this point in the history

Commits on Mar 27, 2026

  1. fix(light): tag dropdown, code highlight (#3799)

    * fix(light): tag dropdown, code highlight
    
    * remove more hardcoded vals
    icecrasher321 authored Mar 27, 2026
    Configuration menu
    Copy the full SHA
    b0980b1 View commit details
    Browse the repository at this point in the history
  2. fix(connectors): contentDeferred pattern + validation fixes across al…

    …l connectors (#3793)
    
    * fix(knowledge): enqueue connector docs per-batch to survive sync timeouts
    
    * fix(connectors): convert all connectors to contentDeferred pattern and fix validation issues
    
    All 10 connectors now use contentDeferred: true in listDocuments, returning
    lightweight metadata stubs instead of downloading content during listing.
    Content is fetched lazily via getDocument only for new/changed documents,
    preventing Trigger.dev task timeouts on large syncs.
    
    Connector-specific fixes from validation audit:
    - Google Drive: metadata-based contentHash, orderBy for deterministic pagination,
      precise maxFiles, byte-length size check with truncation warning
    - OneDrive: metadata-based contentHash, orderBy for deterministic pagination
    - SharePoint: metadata-based contentHash, byte-length size check
    - Dropbox: metadata-based contentHash using content_hash field
    - Notion: code/equation block extraction, empty page fallback to title,
      reduced CHILD_PAGE_CONCURRENCY to 5, syncContext parameter
    - Confluence: syncContext caching for cloudId, reduced label concurrency to 5
    - Gmail: use joinTagArray for label tags
    - Obsidian: syncRunId-based stub hash for forced re-fetch, mtime-based hash
      in getDocument, .trim() on vaultUrl, lightweight validateConfig
    - Evernote: retryOptions threaded through apiFindNotesMetadata and apiGetNote
    - GitHub: added contentDeferred: false to getDocument, syncContext parameter
    
    Infrastructure:
    - sync-engine: added syncRunId to syncContext for Obsidian change detection
    - confluence/utils: replaced raw fetch with fetchWithRetry, added retryOptions
    - oauth: added supportsRefreshTokenRotation: false for Dropbox
    - Updated add-connector and validate-connector skills with contentDeferred docs
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix(connectors): address PR review comments - metadata merge, retryOptions, UTF-8 safety
    
    - Sync engine: merge metadata from getDocument during deferred hydration,
      so Gmail/Obsidian/Confluence tags and metadata survive the stub→full transition
    - Evernote: pass retryOptions {retries:3, backoff:500} from listDocuments and
      getDocument callers into apiFindNotesMetadata and apiGetNote
    - Google Drive + SharePoint: safe UTF-8 truncation that walks back to the last
      complete character boundary instead of splitting multi-byte chars
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix(evernote): use correct RetryOptions property names
    
    maxRetries/initialDelayMs instead of retries/backoff to match the
    RetryOptions interface from lib/knowledge/documents/utils.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix(sync-engine): merge title from getDocument and skip unchanged docs after hydration
    
    - Merge title from getDocument during deferred hydration so Gmail
      documents get the email Subject header instead of the snippet text
    - After hydration, compare the hydrated contentHash against the stored
      DB hash — if they match, skip the update. This prevents Obsidian
      (and any connector with a force-refresh stub hash) from re-uploading
      and re-processing unchanged documents every sync
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix(sync-engine): dedup externalIds, enable deletion reconciliation, merge sourceUrl
    
    Three sync engine gaps identified during audit:
    
    1. Duplicate externalId guard: if a connector returns the same externalId
       across pages (pagination overlap), skip the second occurrence to prevent
       unique constraint violations on add and double-uploads on update.
    
    2. Deletion reconciliation: previously required explicit fullSync or
       syncMode='full', meaning docs deleted from the source accumulated in
       the KB forever. Now runs on all non-incremental syncs (which return
       ALL docs). Includes a safety threshold: if >50% of existing docs
       (and >5 docs) would be deleted, skip and warn — protects against
       partial listing failures. Explicit fullSync bypasses the threshold.
    
    3. sourceUrl merge: hydration now picks up sourceUrl from getDocument,
       falling back to the stub's sourceUrl if getDocument doesn't set one.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * lint
    
    * fix(connectors): confluence version metadata fallback and google drive maxFiles guard
    
    - Confluence: use `version?.number` directly (undefined) in metadata instead
      of `?? ''` (empty string) to prevent Number('') = 0 passing NaN check in
      mapTags. Hash still uses `?? ''` for string interpolation.
    - Google Drive: add early return when previouslyFetched >= maxFiles to prevent
      effectivePageSize <= 0 which violates the API's pageSize requirement (1-1000).
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix(connectors): blogpost labels and capped listing deletion reconciliation
    
    - Confluence: fetchLabelsForPages now tries both /pages/{id}/labels and
      /blogposts/{id}/labels, preventing label loss when getDocument hydrates
      blogpost content (previously returned empty labels on 404).
    - Sync engine: skip deletion reconciliation when listing was capped
      (maxFiles/maxThreads). Connectors signal this via syncContext.listingCapped.
      Prevents incorrect deletion of docs beyond the cap that still exist in source.
      fullSync override still forces deletion for explicit cleanup.
    - Google Drive & Gmail: set syncContext.listingCapped = true when cap is hit.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix(connectors): set syncContext.listingCapped in all connectors with caps
    
    OneDrive, Dropbox, SharePoint, Confluence (v2 + CQL), and Notion (3 listing
    functions) now set syncContext.listingCapped = true when their respective
    maxFiles/maxPages limit is hit. Without this, the sync engine's deletion
    reconciliation would run against an incomplete listing and incorrectly
    hard-delete documents that exist in the source but fell outside the cap window.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix(evernote): thread retryOptions through apiListTags and apiListNotebooks
    
    All calls to apiListTags and apiListNotebooks in both listDocuments and
    getDocument now pass retryOptions for consistent retry protection across
    all Thrift RPC calls.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    ---------
    
    Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
    waleedlatif1 and claude authored Mar 27, 2026
    Configuration menu
    Copy the full SHA
    4c474e0 View commit details
    Browse the repository at this point in the history
  3. feat(search): add tables, files, knowledge bases, and jobs to cmd-k s…

    …earch (#3800)
    
    * feat(search): add tables, files, knowledge bases, and jobs to cmd-k search
    
    * fix(search): address PR feedback — drop files/jobs, add onSelect to memo
    
    * fix(search): add files back with per-file deep links, keep jobs out
    
    * fix(search): remove onSelect from memo comparator to match existing pattern
    waleedlatif1 authored Mar 27, 2026
    Configuration menu
    Copy the full SHA
    e70e1ec View commit details
    Browse the repository at this point in the history
  4. fix(ui): Change modal field to be company size (#3801)

    * Change modal field to be company size
    
    * Adjust dropdown options
    
    * Fix lint
    
    ---------
    
    Co-authored-by: Theodore Li <theo@sim.ai>
    TheodoreSpeaks and Theodore Li authored Mar 27, 2026
    Configuration menu
    Copy the full SHA
    50e42c2 View commit details
    Browse the repository at this point in the history
  5. improvement(terminal): performance improvements (#3796)

    * improvement(terminal): prevent canvas crashes
    
    * checkpoint
    
    * make persistence execution scoped not debounce
    
    * revert feature flags
    
    * address bugbot comments
    
    * fix test
    
    * fix
    
    * fix type
    
    * fix abortion of manual run
    
    * fix type errors
    
    * fix diff comment
    
    * fix chat history query
    
    * fix comment
    
    * Ignore previously executed tool call ids
    
    * fix eval input color
    
    * fix copilot run workflow
    
    * fix tests
    
    ---------
    
    Co-authored-by: Theodore Li <theo@sim.ai>
    icecrasher321 and Theodore Li authored Mar 27, 2026
    Configuration menu
    Copy the full SHA
    ed56451 View commit details
    Browse the repository at this point in the history
  6. feat(generic): add generic resource tab, refactor home structure, and…

    … UI polish (#3803)
    
    * feat(generic): add generic resource tab, refactor home structure, and UI polish
    
    * reverted hardcoded ff
    
    * fix build
    
    * styling consistency
    
    * styling
    
    * fix(auth): extract shared auth button class and align SSO primary style
    
    - Extract AUTH_SUBMIT_BTN constant to (auth)/components/auth-button-classes.ts,
      replacing 10 copy-pasted identical className strings across 7 files
    - Update SSOLoginButton primary variant to use AUTH_SUBMIT_BTN instead of
      hardcoded purple gradient, making it consistent with all other auth form
      submit buttons
    - Fix missing isEphemeralResource import in lib/copilot/resources.ts
      (was re-exported but not available in local scope)
    
    * fix(auth): replace inline button class in chat auth components with AUTH_SUBMIT_BTN
    
    * fix send button hover state
    waleedlatif1 authored Mar 27, 2026
    Configuration menu
    Copy the full SHA
    5f1d5e0 View commit details
    Browse the repository at this point in the history
  7. v0.6.13: emcn standardization, granola and ketch integrations, securi…

    …ty hardening, connectors improvements
    waleedlatif1 authored Mar 27, 2026
    Configuration menu
    Copy the full SHA
    e615816 View commit details
    Browse the repository at this point in the history
Loading