Commit Graph

4203 Commits

Author SHA1 Message Date
waleed
ef82ce635c fix(polling): remove extraneous comment from calendar poller 2026-04-09 19:16:54 -07:00
waleed
d1ae3b291a fix(polling): don't advance calendar timestamp to client clock on empty poll 2026-04-09 19:15:57 -07:00
waleed
033d2eeb34 fix(polling): use position-only idempotency key for sheets rows 2026-04-09 19:04:37 -07:00
waleed
5c53822854 fix(triggers): handle trigger-advanced mode in deploy, preview, params, and copilot 2026-04-09 18:59:20 -07:00
waleed
dddd642e41 test(blocks): handle trigger-advanced mode in canonical validation tests 2026-04-09 18:50:29 -07:00
waleed
2180127513 feat(triggers): add canonical selector toggle to google polling triggers
- Add 'trigger-advanced' mode to SubBlockConfig so canonical pairs work in trigger mode
- Fix buildCanonicalIndex: trigger-mode subblocks don't overwrite non-trigger basicId, deduplicate advancedIds from block spreads
- Update editor, subblock layout, and trigger config aggregation to include trigger-advanced subblocks
- Replace dropdown+fetchOptions in Calendar/Sheets/Drive pollers with file-selector (basic) + short-input (advanced) canonical pairs
- Add canonicalParamId: 'oauthCredential' to triggerCredentials for selector context resolution
- Update polling handlers to read canonical fallbacks (calendarId||manualCalendarId, etc.)
2026-04-09 18:24:10 -07:00
waleed
f89a70a88a fix(polling): revert drive cursor on any failure, not just all-fail 2026-04-09 18:24:10 -07:00
waleed
7d383be8e4 fix(polling): revert calendar timestamp on any failure, not just all-fail 2026-04-09 18:24:10 -07:00
waleed
9c8640f578 fix(polling): retry failed idempotency keys, fix drive cursor overshoot, fix calendar inclusive updatedMin 2026-04-09 18:24:10 -07:00
waleed
a8baa49450 fix(polling): don't advance state when all events fail across sheets, calendar, drive handlers 2026-04-09 18:24:10 -07:00
Waleed Latif
d32e1cbb81 fix(polling): remove unused variable and preserve lastModifiedTime on Drive API failure
- Remove unused `now` variable from Google Drive polling handler
- Preserve stored lastModifiedTime when Drive API pre-check fails
  (previously wrote undefined, disabling the optimization until the
  next successful Drive API call)
2026-04-09 18:24:10 -07:00
Waleed Latif
9df3c078ae fix(polling): prevent data loss on partial row failures and harden idempotency key
- Sheets: only advance lastKnownRowCount by processedCount when there
  are failures, so failed rows are retried on the next poll cycle
  (idempotency deduplicates already-processed rows on re-fetch)
- Drive: add fallback for change.time in idempotency key to prevent
  key collisions if the field is ever absent from the API response
2026-04-09 18:24:10 -07:00
Waleed Latif
cfcc208728 fix(polling): address PR review feedback for Google polling handlers
- Fix fetchHeaderRow to throw on 403/429 rate limits instead of silently
  returning empty headers (prevents rows from being processed without
  headers and lastKnownRowCount from advancing past them permanently)
- Fix Drive pagination to avoid advancing resume cursor past sliced
  changes (prevents permanent change loss when allChanges > maxFiles)
- Remove unused logger import from Google Drive trigger config
2026-04-09 18:24:10 -07:00
Waleed Latif
e563f6d51a chore(lint): fix import ordering in triggers registry
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 18:24:10 -07:00
Waleed Latif
43ce2cc5cd fix(polling): fix Drive pre-check never activating in Sheets poller
isDriveFileUnchanged short-circuited when lastModifiedTime was
undefined, never calling the Drive API — so currentModifiedTime
was never populated, creating a permanent chicken-and-egg loop.
Now always calls the Drive API and returns the modifiedTime
regardless of whether there's a previous value to compare against.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 18:24:10 -07:00
Waleed Latif
a89841392f fix(polling): address PR review feedback for Google polling triggers
- Fix Drive cursor stall: use nextPageToken as resume point when
  breaking early from pagination instead of re-using the original token
- Eliminate redundant Drive API call in Sheets poller by returning
  modifiedTime from the pre-check function
- Add 403/429 rate-limit handling to Sheets API calls matching the
  Calendar handler pattern
- Remove unused changeType field from DriveChangeEntry interface
- Rename triggers/google_drive to triggers/google-drive for consistency

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 18:24:10 -07:00
Waleed Latif
06b68f7463 feat(trigger): add Google Sheets, Drive, and Calendar polling triggers
Add polling triggers for Google Sheets (new rows), Google Drive (file
changes via changes.list API), and Google Calendar (event updates via
updatedMin). Each includes OAuth credential support, configurable
filters (event type, MIME type, folder, search term, render options),
idempotency, and first-poll seeding. Wire triggers into block configs
and regenerate integrations.json. Update add-trigger skill with polling
instructions and versioned block wiring guidance.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 18:24:10 -07:00
Theodore Li
4074109362 fix(log): log cleanup sql query (#4087)
* fix(log): log cleanup sql query

* perf(log): use startedAt index for cleanup query filter

Switch cleanup WHERE clause from createdAt to startedAt to leverage
the existing composite index (workspaceId, startedAt), converting a
full table scan to an index range scan. Also remove explanatory comment.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Theodore Li <theo@sim.ai>
Co-authored-by: Waleed Latif <walif6@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 18:04:15 -07:00
Waleed
171485d3b6 fix(tools): handle all Atlassian error formats in parseJsmErrorMessage (#4088)
Update parseJsmErrorMessage to extract errors from all Atlassian API
response formats: errorMessage (JSM), errorMessages array (Jira),
errors[].title RFC 7807 (Confluence/Forms), field-level errors object,
and message (gateway). Remove redundant prefix wrapping so the raw
error message surfaces cleanly through the extractor.
2026-04-09 17:08:19 -07:00
Waleed
bce638dd75 fix(tools): add Atlassian error extractor to all Jira, JSM, and Confluence tools (#4085)
* fix(tools): add Atlassian error extractor to all Jira, JSM, and Confluence tools

Wire up the existing `atlassian-errors` error extractor to all 95 Atlassian
tool configs so the executor surfaces meaningful error messages instead of
generic status codes. Also fix the extractor itself to handle all three
Atlassian error response formats: `errorMessage` (JSM), `errorMessages`
array (Jira), and `message` (Confluence).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore(tools): lint formatting fix for error extractor

* fix(tools): handle all Atlassian error formats in error extractor

Add RFC 7807 errors[].title format (Confluence v2, Forms/ProForma API)
and Jira field-level errors object to the atlassian-errors extractor.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 15:18:34 -07:00
Waleed
05b5588a7b improvement(ci): parallelize Docker builds and fix test timeouts (#4083)
* improvement(ci): parallelize Docker builds with tests and remove duplicate turbo install

* fix(test): use SecureFetchResponse shape in mock instead of standard Response
2026-04-09 15:18:19 -07:00
Waleed
32bdf3cfa5 fix(trigger): use @react-email/render v2 to fix renderToPipeableStream error (#4084) 2026-04-09 14:46:57 -07:00
Waleed
12deb0f5b4 chore(ci): bump actions/checkout to v6 and dorny/paths-filter to v4 (#4082)
* chore(ci): bump actions/checkout to v6 and dorny/paths-filter to v4

* fix(ci): mock secureFetchWithPinnedIP in tools tests to prevent timeouts

* lint
2026-04-09 14:33:11 -07:00
Waleed
c393791f04 docs(openapi): add Human in the Loop API endpoints (#4079)
* docs(openapi): add Human in the Loop API endpoints

Add HITL pause/resume endpoints to the OpenAPI spec covering
the full workflow pause lifecycle: listing paused executions,
inspecting pause details, and resuming with input.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(openapi): add 403 and 500 responses to HITL endpoints

Address PR review feedback: add missing 403 Forbidden response
to all HITL endpoints (from validateWorkflowAccess), and 500
responses to resume endpoints that have explicit error paths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* lint

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 14:01:09 -07:00
Waleed
fc3e762b1f feat(trigger): add ServiceNow webhook triggers (#4077)
* feat(trigger): add ServiceNow webhook triggers

* fix(trigger): add webhook secret field and remove non-TSDoc comment

Add webhookSecret field to ServiceNow triggers (matching Salesforce pattern)
so users are prompted to protect the webhook endpoint. Update setup
instructions to include Authorization header in the Business Rule example.
Remove non-TSDoc inline comment in the block config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(trigger): add ServiceNow provider handler with event matching

Add dedicated ServiceNow webhook provider handler with:
- verifyAuth: validates webhookSecret via Bearer token or X-Sim-Webhook-Secret
- matchEvent: filters events by trigger type and table name using
  isServiceNowEventMatch utility (matching Salesforce/GitHub pattern)

The event matcher handles incident created/updated and change request
created/updated triggers with table name enforcement and event type
normalization. The generic webhook trigger passes through all events
but still respects the optional table name filter.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* lint

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 13:59:07 -07:00
Waleed
70f04c003b feat(jsm): add ProForma/JSM Forms discovery tools (#4078)
* feat(jsm): add ProForma/JSM Forms discovery tools

Add three new tools for discovering and inspecting JSM Forms (ProForma) templates
and their structure, enabling dynamic form-based workflows:

- jsm_get_form_templates: List form templates in a project with request type bindings
- jsm_get_form_structure: Get full form design (questions, layout, conditions, sections)
- jsm_get_issue_forms: List forms attached to an issue with submission status

All endpoints validated against the official Atlassian Forms REST API OpenAPI spec.
Uses the Forms Cloud API base URL (jira/forms/cloud/{cloudId}) with X-ExperimentalApi header.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(jsm): add input validation and extract shared error parser

- Add validateJiraIssueKey for projectIdOrKey in templates and structure routes
- Add validateJiraCloudId for formId (UUID) in structure route
- Extract parseJsmErrorMessage to shared utils.ts (was duplicated across 3 routes)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore(jsm): remove unused FORM_QUESTION_PROPERTIES constant

Dead code — the get_form_structure tool passes the raw design object
through as JSON, so this output constant had no consumers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 13:58:41 -07:00
Waleed
7bd271ae5b fix(credentials): add cross-cache invalidation for oauth credential queries (#4076) 2026-04-09 11:32:08 -07:00
Waleed
8e222fa369 improvement(polling): fix correctness and efficiency across all polling handlers (#4067)
* improvement(polling): fix correctness and efficiency across all polling handlers

- Gmail: paginate history API, add historyTypes filter, differentiate 403/429,
  fetch fresh historyId on fallback to break 404 retry loop
- Outlook: follow @odata.nextLink pagination, use fetchWithRetry for all Graph
  calls, fix $top alignment, skip folder filter on partial resolution failure,
  remove Content-Type from GET requests
- RSS: add conditional GET (ETag/If-None-Match), raise GUID cap to 500, fix 304
  ETag capture per RFC 9111, align GUID tracking with idempotency fallback key
- IMAP: single connection reuse, UIDVALIDITY tracking per mailbox, advance UID
  only on successful fetch, fix messageFlagsAdd range type, remove cross-mailbox
  legacy UID fallback
- Dispatch polling via trigger.dev task with per-provider concurrency key;
  fall back to synchronous Redis-locked polling for self-hosted

* fix(rss): align idempotency key GUID fallback with tracking/filter guard

* removed comments

* fix(imap): clear stale UID when UIDVALIDITY changes during state merge

* fix(rss): skip items with no identifiable GUID to avoid idempotency key collisions

* fix(schedules): convert dynamic import of getWorkflowById to static import

* fix(imap): preserve fresh UID after UIDVALIDITY reset in state merge

* improvement(polling): remove trigger.dev dispatch, use synchronous Redis-locked polling

* fix(polling): decouple outlook page size from total email cap so pagination works
2026-04-09 11:22:38 -07:00
Waleed
b67c068817 improvement(deploy): improve auto-generated version descriptions (#4075)
* improvement(deploy): improve auto-generated version descriptions

* fix(deploy): address PR review - log dropdown errors, populate first-deploy details

* lint
2026-04-09 10:51:46 -07:00
Waleed
d778b3d35b fix(trigger): add @react-email/components to additionalPackages (#4068) 2026-04-08 23:26:30 -07:00
Vikhyath Mondreti
dc7d876a34 improvement(release): address comments (#4069) 2026-04-08 23:22:18 -07:00
Waleed
db230785d3 fix(jsm): improve create request error handling, add form-based submission support (#4066)
* fix(jsm): improve create request error handling, add form-based submission support

* refactor(jsm): extract parseJsmErrorMessage helper to deduplicate error handling

* fix(jsm): remove required on summary for advanced mode, add JSON.parse error handling

* fix(jsm): include description in requestFieldValues gate for form-only requests
2026-04-08 22:17:01 -07:00
Vikhyath Mondreti
9fbe514dbd fix(hitl): resume workflow output async (#4065) 2026-04-08 19:31:18 -07:00
Theodore Li
139213ef45 feat(block): Add cloudwatch publish operation (#4027)
* feat(block): Add cloudwatch publish operation

* fix(integrations): validate and fix cloudwatch, cloudformation, athena conventions

- Update tool version strings from '1.0' to '1.0.0' across all three integrations
- Add missing `export * from './types'` barrel re-exports (cloudwatch, cloudformation)
- Add docsLink, wandConfig timestamps, mode: 'advanced' on optional fields (cloudwatch)
- Add dropdown defaults, ZodError handling, docs intro section (cloudwatch)
- Add mode: 'advanced' on limit field (cloudformation)
- Alphabetize registry entries (cloudwatch, cloudformation)
- Fix athena docs maxResults range (1-999)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cloudwatch): complete put_metric_data unit dropdown, add missing outputs, fix JSON error handling

- Add all 27 valid CloudWatch StandardUnit values to metricUnit dropdown (was 13)
- Add missing block outputs for put_metric_data: success, namespace, metricName, value, unit
- Add try-catch around dimensions JSON.parse in put-metric-data route for proper 400 errors

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cloudwatch): fix DescribeAlarms returning only MetricAlarm when "All Types" selected

Per AWS docs, omitting AlarmTypes returns only MetricAlarm. Now explicitly
sends both MetricAlarm and CompositeAlarm when no filter is selected.

Also fix dimensions JSON parse errors returning 500 instead of 400 in
get-metric-statistics route.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cloudwatch): validate dimensions JSON at Zod schema level

Move dimensions validation from runtime try-catch to Zod refinement,
catching malformed JSON and arrays at schema validation time (400)
instead of runtime (500). Also rejects JSON arrays that would produce
meaningless numeric dimension names.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cloudwatch): reject non-numeric metricValue instead of silently publishing 0

Add NaN guard in block config and .finite() refinement in Zod schema
so "abc" → NaN is caught at both layers instead of coercing to 0.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cloudwatch): use Number.isFinite to also reject Infinity in block config

Aligns block-level validation with route's Zod .finite() refinement so
Infinity/-Infinity are caught at the block config layer, not just the API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Theodore Li <teddy@zenobiapay.com>
Co-authored-by: Waleed Latif <walif6@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 19:02:24 -07:00
Vikhyath Mondreti
a8468a6056 fix(hitl): async resume (#4064)
* fix(hitl): async resume

* fix
2026-04-08 18:46:16 -07:00
Vikhyath Mondreti
3e85218142 improvement(hitl): streaming, async support + update docs (#4058)
* improvement(hitl): support streaming, async, update docs

* update docs

* fix tests

* fix abort signal passthrough

* module level const

* fix form route

* address comments

* fix build
2026-04-08 17:36:33 -07:00
Vikhyath Mondreti
c5cc336847 fix(subscription-state): remove dead code, change token route check (#4062)
* fix(subscription-state): remove dead code, change token route check

* update tests

* remove mock

* improve ux past usage limit
2026-04-08 17:17:32 -07:00
Theodore Li
5f33432dc2 fix(billing): Skip billing on streamed workflows with byok (#4056)
* fix(billing): skip billing on streamed workflows with byok

* Simplify logic

* Address comments, skip tokenization billing fallback

* Fix tool usage billing for streamed outputs

* fix(webhook): throw webhook errors as 4xxs (#4050)

* fix(webhook): throw webhook errors as 4xxs

* Fix shadowing body var

---------

Co-authored-by: Theodore Li <theo@sim.ai>

* feat(enterprise): cloud whitelabeling for enterprise orgs (#4047)

* feat(enterprise): cloud whitelabeling for enterprise orgs

* fix(enterprise): scope enterprise plan check to target org in whitelabel PUT

* fix(enterprise): use isOrganizationOnEnterprisePlan for org-scoped enterprise check

* fix(enterprise): allow clearing whitelabel fields and guard against empty update result

* fix(enterprise): remove webp from logo accept attribute to match upload hook validation

* improvement(billing): use isBillingEnabled instead of isProd for plan gate bypasses

* fix(enterprise): show whitelabeling nav item when billing is enabled on non-hosted environments

* fix(enterprise): accept relative paths for logoUrl since upload API returns /api/files/serve/ paths

* fix(whitelabeling): prevent logo flash on refresh by hiding logo while branding loads

* fix(whitelabeling): wire hover color through CSS token on tertiary buttons

* fix(whitelabeling): show sim logo by default, only replace when org logo loads

* fix(whitelabeling): cache org logo url in localstorage to eliminate flash on repeat visits

* feat(whitelabeling): add wordmark support with drag/drop upload

* updated turbo

* fix(whitelabeling): defer localstorage read to effect to prevent hydration mismatch

* fix(whitelabeling): use layout effect for cache read to eliminate logo flash before paint

* fix(whitelabeling): cache theme css to eliminate color flash before org settings resolve

* fix(whitelabeling): deduplicate HEX_COLOR_REGEX into lib/branding and remove mutation from useCallback deps

* fix(whitelabeling): use cookie-based SSR cache to eliminate brand flash on all page loads

* fix(whitelabeling): use !orgSettings condition to fix SSR brand cache injection

React Query returns isLoading: false with data: undefined during SSR, so the
previous brandingLoading condition was always false on the server — initialCache
was never injected into brandConfig. Changing to !orgSettings correctly applies
the cookie cache both during SSR and while the client-side query loads, eliminating
the logo flash on hard refresh.

* fix(editor): stop highlighting start.input as blue when block is not connected to starter (#4054)

* fix: merge subblock values in auto-layout to prevent losing router context (#4055)

Auto-layout was reading from getWorkflowState() without merging subblock
store values, then persisting stale subblock data to the database. This
caused runtime-edited values (e.g. router_v2 context) to be overwritten
with their initial/empty values whenever auto-layout was triggered.

* fix(whitelabeling): eliminate logo flash by fetching org settings server-side (#4057)

* fix(whitelabeling): eliminate logo flash by fetching org settings server-side

* improvement(whitelabeling): add SVG support for logo and wordmark uploads

* skelly in workspace header

* remove dead code

* fix(whitelabeling): hydration error, SVG support, skeleton shimmer, dead code removal

* fix(whitelabeling): blob preview dep cycle and missing color fallback

* fix(whitelabeling): use brand-accent as color fallback when workspace color is undefined

* chore(whitelabeling): inline hasOrgBrand

---------

Co-authored-by: Theodore Li <theo@sim.ai>
2026-04-08 19:24:04 -04:00
Theodore Li
c83349200c fix(error): catch socket auth error as 4xx (#4059)
* fix(error): catch socket auth error as 4xx

* Switch to type guard

---------

Co-authored-by: Theodore Li <theo@sim.ai>
2026-04-08 19:07:30 -04:00
waleed
1856635927 fix(whitelabeling): cast activeOrganizationId on session for TS build 2026-04-08 15:54:51 -07:00
Waleed
91ce55e547 fix(whitelabeling): eliminate logo flash by fetching org settings server-side (#4057)
* fix(whitelabeling): eliminate logo flash by fetching org settings server-side

* improvement(whitelabeling): add SVG support for logo and wordmark uploads

* skelly in workspace header

* remove dead code

* fix(whitelabeling): hydration error, SVG support, skeleton shimmer, dead code removal

* fix(whitelabeling): blob preview dep cycle and missing color fallback

* fix(whitelabeling): use brand-accent as color fallback when workspace color is undefined

* chore(whitelabeling): inline hasOrgBrand
2026-04-08 14:07:31 -07:00
Waleed
694f4a5895 fix: merge subblock values in auto-layout to prevent losing router context (#4055)
Auto-layout was reading from getWorkflowState() without merging subblock
store values, then persisting stale subblock data to the database. This
caused runtime-edited values (e.g. router_v2 context) to be overwritten
with their initial/empty values whenever auto-layout was triggered.
2026-04-08 13:25:15 -07:00
Waleed
4700590e64 fix(editor): stop highlighting start.input as blue when block is not connected to starter (#4054) 2026-04-08 12:51:13 -07:00
Waleed
1189400167 feat(enterprise): cloud whitelabeling for enterprise orgs (#4047)
* feat(enterprise): cloud whitelabeling for enterprise orgs

* fix(enterprise): scope enterprise plan check to target org in whitelabel PUT

* fix(enterprise): use isOrganizationOnEnterprisePlan for org-scoped enterprise check

* fix(enterprise): allow clearing whitelabel fields and guard against empty update result

* fix(enterprise): remove webp from logo accept attribute to match upload hook validation

* improvement(billing): use isBillingEnabled instead of isProd for plan gate bypasses

* fix(enterprise): show whitelabeling nav item when billing is enabled on non-hosted environments

* fix(enterprise): accept relative paths for logoUrl since upload API returns /api/files/serve/ paths

* fix(whitelabeling): prevent logo flash on refresh by hiding logo while branding loads

* fix(whitelabeling): wire hover color through CSS token on tertiary buttons

* fix(whitelabeling): show sim logo by default, only replace when org logo loads

* fix(whitelabeling): cache org logo url in localstorage to eliminate flash on repeat visits

* feat(whitelabeling): add wordmark support with drag/drop upload

* updated turbo

* fix(whitelabeling): defer localstorage read to effect to prevent hydration mismatch

* fix(whitelabeling): use layout effect for cache read to eliminate logo flash before paint

* fix(whitelabeling): cache theme css to eliminate color flash before org settings resolve

* fix(whitelabeling): deduplicate HEX_COLOR_REGEX into lib/branding and remove mutation from useCallback deps

* fix(whitelabeling): use cookie-based SSR cache to eliminate brand flash on all page loads

* fix(whitelabeling): use !orgSettings condition to fix SSR brand cache injection

React Query returns isLoading: false with data: undefined during SSR, so the
previous brandingLoading condition was always false on the server — initialCache
was never injected into brandConfig. Changing to !orgSettings correctly applies
the cookie cache both during SSR and while the client-side query loads, eliminating
the logo flash on hard refresh.
2026-04-08 12:33:26 -07:00
Theodore Li
621aa65b91 fix(webhook): throw webhook errors as 4xxs (#4050)
* fix(webhook): throw webhook errors as 4xxs

* Fix shadowing body var

---------

Co-authored-by: Theodore Li <theo@sim.ai>
2026-04-08 15:30:12 -04:00
Waleed
c21876ab40 fix(trigger): add react-dom and react-email to additionalPackages (#4052) 2026-04-08 11:39:06 -07:00
Theodore Li
a1173ee712 debug(log): Add logging on socket token error (#4051)
Co-authored-by: Theodore Li <theo@sim.ai>
2026-04-08 14:36:02 -04:00
Waleed
579d240cee fix(parallel): remove broken node-counting completion + resolver claim cross-block (#4045)
* fix(parallel): remove broken node-counting completion in parallel blocks

* fix resolver claim

---------

Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai>
2026-04-08 11:05:23 -07:00
Waleed
04c9057229 fix(kb): disable connectors after repeated sync failures (#4046)
* fix(kb): improve error logging when connector token resolution fails

The generic "Failed to obtain access token" error hid the actual root cause.
Now logs credentialId, userId, authMode, and provider to help diagnose
token refresh failures in trigger.dev.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(kb): disable connectors after 10 consecutive sync failures

Connectors that fail 10 times in a row are set to 'disabled' status,
stopping the cron from scheduling further syncs. The UI shows an alert
triangle with a reconnect banner. Users can re-enable via the play
button or by reconnecting their account, which resets failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(kb): disable sync button for disabled connectors, use amber badge variant

Sync button should be disabled when connector is in disabled state to
guide users toward reconnecting first. Badge variant changed from red
to amber to match the warning banner styling.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(kb): address PR review comments for disabled connector feature

- Use `=== undefined` instead of falsy check for nextSyncAt to preserve
  explicit null (manual sync only) when syncIntervalMinutes is 0
- Gate Reconnect button on serviceId/providerId so it only renders for
  OAuth connectors; show appropriate copy for API key connectors

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(kb): move resolveAccessToken inside try/catch for circuit-breaker coverage

Token resolution failures (e.g. revoked OAuth tokens) were thrown before
the try/catch block, bypassing consecutiveFailures tracking entirely.
Also removes dead `if (refreshed)` guards at mid-sync refresh sites since
resolveAccessToken now always returns a string or throws.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(kb): remove dead interval branch when re-enabling connector

When `updates.nextSyncAt === undefined`, syncIntervalMinutes was not in
the request, so `parsed.data.syncIntervalMinutes` is always undefined.
Simplify to just schedule an immediate sync — the sync engine sets the
proper nextSyncAt based on the connector's DB interval after completion.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 10:41:06 -07:00
Vikhyath Mondreti
650487c3c9 fix(kb): doc selector (#4048) 2026-04-08 10:28:14 -07:00