v0.5.113: jira, ashby, google ads, grain updates#3557
Conversation
#3547) Issue keys are self-sufficient identifiers in Jira (e.g., PROJ-123). The manualIssueKey field is a text input where users type the key directly, so it should not depend on projectId/manualProjectId. This dependency caused the field to clear unnecessarily when the project selection changed.
…#3548) * feat(ashby): add webhook triggers with automatic lifecycle management * fix(ashby): address PR review comments - Restore mode: 'advanced' on updateName sub-block - Move action after spread in formatWebhookInput to prevent override - Remove generic webhook trigger (Ashby requires webhookType) * fix(ashby): throw on unknown triggerId, always include webhookType * fix(ashby): address PR review feedback - paramVisibility, stageType, json catch - Add paramVisibility: 'user-only' to apiKey extra field - Remove stageType from candidateStageChange/candidateHire outputs (TriggerOutput type conflict with 'type' field) - Add .catch() fallback to .json() parse in createAshbyWebhookSubscription - Fix candidateStageChange outputs to match actual Ashby application payload structure * fix(ashby): add missing applicationSubmit outputs, fix delete log branches - Add candidate, currentInterviewStage, job to applicationSubmit outputs - Split delete webhook log into ok/404/error branches for accurate logging * fix(ashby): drain response body on delete, clarify decidedAt description - Cancel unconsumed response body in ok/404 delete branches to free connections - Update decidedAt description to note it's typically null at offer creation * fix(ashby): eliminate double-logging, fix hiringTeam JSDoc - Remove pre-throw warn/error logs; catch block is single logging point - Remove hiringTeam from candidateHire JSDoc (TriggerOutput doesn't support arrays)
#3551) * fix(executor): skip Response block formatting for internal JWT callers The workflow executor tool received `{error: true}` despite successful child workflow execution when the child had a Response block. This happened because `createHttpResponseFromBlock()` hijacked the response with raw user-defined data, and the executor's `transformResponse` expected the standard `{success, executionId, output, metadata}` wrapper. Fix: skip Response block formatting when `authType === INTERNAL_JWT` since Response blocks are designed for external API consumers, not internal workflow-to-workflow calls. Also extract `AuthType` constants from magic strings across all auth type comparisons in the codebase. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test(executor): add route-level tests for Response block auth gating Verify that internal JWT callers receive standard format while external callers (API key, session) get Response block formatting. Tests the server-side condition directly using workflowHasResponseBlock and createHttpResponseFromBlock with AuthType constants. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(testing): add AuthType to all hybrid auth test mocks Route code now imports AuthType from @/lib/auth/hybrid, so test mocks must export it too. Added AuthTypeMock to @sim/testing and included it in all 15 test files that mock the hybrid auth module. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…ormance queries (#3360) * feat(google-ads): add google ads integration for campaign and ad performance queries * fix(google-ads): add input validation for GAQL query parameters * fix(google-ads): remove deprecated pageSize param, fix searchSettings nesting, add missing date ranges * fix(google-ads): validate managerCustomerId before use in login-customer-id header * chore(docs): regenerate docs after google ads integration * fix(google-ads): use centralized scope utilities and add type re-export - Replace hardcoded scopes in auth.ts with getCanonicalScopesForProvider('google-ads') - Replace hardcoded requiredScopes in block with getScopesForService('google-ads') - Add type re-export from index.ts barrel Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(google-ads): add userinfo scopes to oauth provider config Align google-ads with all other Google services by including userinfo.email and userinfo.profile scopes in the centralized OAUTH_PROVIDERS config. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * lint --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(grain): update to stable version of API * fix prewebhook lookup * update pending webhook verification infra * add generic webhook test event verification subblock
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryHigh Risk Overview Expands webhook capabilities by introducing managed Ashby webhook triggers (new trigger configs and automatic create/delete lifecycle), plus a new “pending webhook verification” mechanism (Redis/in-memory) so providers like Grain (and optionally generic) can get 200 OK verification responses before a webhook DB row exists; webhook deploy now registers/clears these entries and the trigger route now supports pre-lookup verification for Stabilizes and adjusts existing integrations/infra: Grain webhook APIs are updated to the newer endpoints and now require Written by Cursor Bugbot for commit d90f828. Configure here. |
Greptile SummaryThis PR bundles five distinct improvements: a Jira fix removing unnecessary Key points:
Confidence Score: 3/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant Client as External Provider<br/>(Ashby / Grain)
participant Route as /api/webhooks/trigger/[path]
participant Processor as processor.ts
participant PendingStore as PendingVerification<br/>(Redis / In-Memory)
participant DB as Database
participant Executor as Workflow Executor
Note over Client,PendingStore: Phase 1 – Deploy (URL Probe Window)
Client->>Route: GET/POST probe (URL verification)
Route->>Processor: handlePreLookupWebhookVerification()
Processor->>PendingStore: getPendingWebhookVerification(path)
PendingStore-->>Processor: PendingVerification entry (TTL 120s)
Processor-->>Route: 200 OK { status: "ok" }
Route-->>Client: 200 OK
Note over Client,Executor: Phase 2 – Normal Event Delivery
Client->>Route: POST event payload
Route->>DB: findAllWebhooksForPath(path)
DB-->>Route: webhook record(s)
Route->>Processor: checkWebhookPreprocessing()
Processor->>Processor: shouldSkipWebhookEvent()
Processor->>Executor: preprocessExecution()
Executor-->>Route: ExecutionResult
Route-->>Client: 200 OK
Note over Client,Executor: Phase 3 – Internal JWT (A2A / sub-workflow)
Client->>Route: POST /workflows/[id]/execute (internal_jwt)
Route->>Executor: execute workflow
Executor-->>Route: ExecutionResult (with Response block)
alt auth.authType === INTERNAL_JWT
Route-->>Client: Standard JSON result (no HTTP-block formatting)
else API key / Session
Route-->>Client: HTTP response shaped by Response block
end
|
| return extractPageData(body) | ||
| } | ||
|
|
||
| if (foundWebhook.provider === 'ashby') { | ||
| return { | ||
| ...(body.data || {}), | ||
| action: body.action, | ||
| data: body.data || {}, | ||
| } | ||
| } |
There was a problem hiding this comment.
Redundant data in Ashby webhook output
The Ashby formatter spreads the contents of body.data at the top level AND re-attaches it under the data key. This means every event field (e.g. application, candidate) appears twice in the workflow output — once at the root and once nested under data.
This dual representation isn't harmful, but it diverges from the output schemas defined in triggers/ashby/utils.ts, which only declare top-level output keys (no nested data). Users who inadvertently reference output.data.application instead of output.application will get the same value, which could mask configuration mistakes or confuse debugging.
Consider removing the redundant data key to keep the output schema consistent with the declared trigger outputs:
| return extractPageData(body) | |
| } | |
| if (foundWebhook.provider === 'ashby') { | |
| return { | |
| ...(body.data || {}), | |
| action: body.action, | |
| data: body.data || {}, | |
| } | |
| } | |
| if (foundWebhook.provider === 'ashby') { | |
| return { | |
| ...(body.data || {}), | |
| action: body.action, | |
| } | |
| } |
Summary