* refactor(utils): consolidate duplicated helpers onto @sim/utils
Replaces ~90 hand-rolled reimplementations of error-message extraction,
postgres error-code checks, sleep, Math.random, retry/backoff, object
filtering/omission, noop, string truncation, date/time formatting, email
normalization, and plain-object type guards with the shared @sim/utils
exports. Wires check:utils into CI (test-build.yml) so these patterns
don't regress.
* fix(test): mock @sim/utils/random instead of Math.random in schedule-execute tests
The schedules/execute route previously used Math.random() for jitter delay;
this consolidation PR switched it to randomInt() from @sim/utils/random,
which is backed by crypto.getRandomValues() rather than Math.random(). The
route.test.ts spies on Math.random() no longer had any effect, so jitter
became real random delay instead of the deterministic 0ms the tests expect,
causing intermittent 10s timeouts in CI.
* fix(retry): preserve uncapped Retry-After comparison in tools/index.ts
parseRetryAfter() caps its return value at 30s by default. tools/index.ts
compares the parsed Retry-After against a caller-configured maxDelayMs to
decide whether to skip a retry entirely -- capping before that comparison
silently defeats the skip check whenever maxDelayMs is configured above
30s, since a Retry-After between 30s and maxDelayMs would incorrectly look
"within limits" and get retried instead of skipped (caught by Cursor
Bugbot). Added an optional maxMs param (default unchanged) so tools/index.ts
can request the raw, uncapped value for its own comparison while
backoffWithJitter still clamps the actual sleep duration to maxDelayMs.
Added a regression test covering maxDelayMs > 30s.
* fix(utils): fall back to Intl-resolved abbreviation for unmapped timezones
getTimezoneAbbreviation only covered 9 hardcoded IANA zones and returned
the raw IANA string for everything else, degrading schedule descriptions
for zones like Europe/Berlin or America/Toronto (caught by Greptile). The
deleted local implementation in schedules/utils.ts resolved any valid IANA
timezone generically via Intl.DateTimeFormat's short timeZoneName. Restore
that as a fallback so only genuinely invalid timezone strings return
themselves unchanged.
* feat(tools): added calcom
* added more triggers, tested
* updated regex in script for release to be more lenient
* fix(tag-dropdown): performance improvements and scroll bug fixes
- Add flatTagIndexMap for O(1) tag lookups (replaces O(n²) findIndex calls)
- Memoize caret position calculation to avoid DOM manipulation on every render
- Use refs for inputValue/cursorPosition to keep handleTagSelect callback stable
- Change itemRefs from index-based to tag-based keys to prevent stale refs
- Fix scroll jump in nested folders by removing scroll reset from registerFolder
- Add onFolderEnter callback for scroll reset when entering folder via keyboard
- Disable keyboard navigation wrap-around at boundaries
- Simplify selection reset to single effect on flatTagList.length change
Also:
- Add safeCompare utility for timing-safe string comparison
- Refactor webhook signature validation to use safeCompare
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* updated types
* fix(calcom): simplify required field constraints for booking attendee
The condition field already restricts these to calcom_create_booking,
so simplified to required: true. Per Cal.com API docs, email is optional
while name and timeZone are required.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* added tests
* updated folder multi select, updated calcom and github tools and docs generator script
* updated drag, updated outputs for tools, regen docs with nested docs script
* updated setup instructions links, destructure trigger outputs, fix text subblock styling
* updated docs gen script
* updated docs script
* updated docs script
* updated script
* remove destructuring of stripe webhook
* expanded wand textarea, updated calcom tools
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>