Skip to content

feat(cue): add generic webhook trigger for external events - #1303

Open
pedramamini wants to merge 2 commits into
rcfrom
feat/858-cue-webhook-trigger
Open

feat(cue): add generic webhook trigger for external events#1303
pedramamini wants to merge 2 commits into
rcfrom
feat/858-cue-webhook-trigger

Conversation

@pedramamini

@pedramamini pedramamini commented Jul 25, 2026

Copy link
Copy Markdown
Collaborator

closes #858

Summary

Adds a webhook.received Cue event type so any external service that can send an HTTP POST - GitHub, GitLab, Slack, CI systems, ad-hoc scripts - can trigger a Cue pipeline.

Kept deliberately generic as the issue asked: the delivery lands in the event payload and the existing filter engine decides which deliveries matter, rather than hardcoding per-vendor handling. One endpoint can drive several pipelines:

subscriptions:
  - name: pr-opened
    event: webhook.received
    webhook:
      path: gh-pr
      secret_env: GH_WEBHOOK_SECRET
      signature_header: X-Hub-Signature-256
    filter:
      webhook_event: pull_request   # from X-GitHub-Event
      body.action: opened           # any field in the JSON body
    prompt: |
      A pull request was just opened. Review it.

      {{CUE_WEBHOOK_BODY}}

The listener (src/main/cue/cue-webhook-server.ts)

  • One process-wide listener shared by every webhook subscription across every agent (a port can only be bound once). Refcounted, so the socket only exists while a webhook pipeline is loaded - a user with none never has a listening port.
  • Loopback by default: binds 127.0.0.1:17997. MAESTRO_CUE_WEBHOOK_PORT / MAESTRO_CUE_WEBHOOK_HOST override. Public delivery is expected to go through a tunnel (ngrok, cloudflared) or reverse proxy rather than a public bind.
  • A secret is mandatory. A webhook path with no auth is a remote trigger for an agent running with the user's credentials, so a subscription without secret/secret_env fails config validation rather than quietly starting to listen. secret_env is preferred and the two are mutually exclusive.
  • Two auth modes, both timing-safe:
    • presented secret via X-Maestro-Cue-Secret or Authorization: Bearer
    • HMAC-SHA256 over the raw body via a configured signature_header, accepting the sha256=<hex> form GitHub and GitLab send - so pointing a GitHub webhook at Maestro needs no glue code.
  • Secrets never reach a payload: Authorization, Cookie, X-Maestro-Cue-Secret, and the configured signature header are stripped before the event is built, so they can't leak into a prompt, the activity log, or the Cue DB.
  • POST only (405 otherwise), 1 MB body cap enforced before authentication, unknown paths 404 without revealing whether a secret would have matched. Subscriptions sharing a path each authenticate independently.

Wiring

Trigger source, config normalizer + validator, template-context enricher, and five {{CUE_WEBHOOK_*}} variables (BODY, EVENT, PATH, DELIVERY_ID, HEADERS). The body is pretty-printed JSON, since senders minify and a single-line blob is harder for an agent to reason about.

Pipeline editor gets the trigger in the drawer plus a config panel (path / secret env var / signature header) that writes secret_env, never a literal. A hand-written literal secret still round-trips losslessly so opening and saving a pipeline in the editor can't silently strip a working secret off disk.

Docs

New event section in docs/maestro-cue-events.md, an in-app Cue pattern, and a CueHelpModal entry.

Testing

  • New: 17 listener tests (routing, both auth modes, header redaction, fan-out, size cap, non-JSON bodies) and 12 trigger-source tests (secret resolution, path defaulting, payload shape, filter integration, enabled() gate, idempotent start/stop).
  • New validator + loader coverage for the webhook block.
  • Updated three pre-existing event-type count assertions (10 -> 11, 8 -> 9 drawer items).
  • Full suite green locally: 1401 files, 34682 passing. npm run lint, lint:eslint, and prettier --check clean.

Local run is macOS only - the CI matrix still needs to confirm ubuntu and windows.

Open question for the maintainers

The listener is a standalone http.Server rather than a route on the existing Fastify WebServer. That keeps webhooks working without the user enabling remote web access, and keeps the auth model per-subscription instead of per-app-token. If you'd rather have this live under WebServer (inheriting its rate limiting and tunnel story), the trigger source and registration API stay unchanged - only cue-webhook-server.ts swaps out.

Summary by CodeRabbit

  • New Features

    • Added the webhook.received Cue event type with a local webhook listener and routing to matching subscriptions.
    • Supports required authentication (shared secret or Bearer) and optional HMAC-SHA256 signature verification.
    • Added webhook-specific prompt variables and editor support (configuration, validation, YAML conversion).
    • Expanded trigger/event catalogs to include the new type.
  • Documentation

    • Updated Cue docs and help content, including that Cue supports 11 Maestro Cue event types.
    • Added full webhook.received documentation with security, delivery behavior, filters, and templates.
  • Tests

    • Expanded coverage for validation, signature/body verification, payload handling, redaction, and unregister behavior.

Adds a `webhook.received` Cue event type so any external service that can
send an HTTP POST - GitHub, GitLab, Slack, CI systems, ad-hoc scripts - can
drive a Cue pipeline. Deliberately generic: the payload lands in the event
and the existing filter engine decides which deliveries matter, rather than
hardcoding per-vendor handling.

Listener (src/main/cue/cue-webhook-server.ts):
- One process-wide HTTP listener shared by every webhook subscription across
  every agent, refcounted so the port only exists when a webhook pipeline is
  loaded.
- Binds 127.0.0.1:17997 by default (MAESTRO_CUE_WEBHOOK_PORT /
  MAESTRO_CUE_WEBHOOK_HOST override). Public delivery is expected to go
  through a tunnel or reverse proxy rather than a public bind.
- Every subscription must carry a secret; config validation fails loudly
  without one, since an unauthenticated path is a remote trigger for an
  agent running with the user's credentials.
- Two auth modes: presented secret (X-Maestro-Cue-Secret or Authorization:
  Bearer) or HMAC-SHA256 over the raw body via a configured signature header,
  accepting the sha256=<hex> form GitHub and GitLab send. Both compare
  timing-safe.
- Auth headers are stripped before the payload is built, so secrets can't
  reach a prompt, the activity log, or the Cue DB. POST only, 1 MB body cap.

Wiring: trigger source, config normalizer + validator, template context
enricher, and five {{CUE_WEBHOOK_*}} template variables. Pipeline editor gets
the trigger in the drawer, a config panel (path / secret env var / signature
header) that writes secret_env rather than literals, and lossless YAML
round-tripping for hand-written configs.

Docs: new event section in docs/maestro-cue-events.md, an in-app pattern, and
a CueHelpModal entry.

closes #858
@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds the webhook.received Cue event with authenticated shared HTTP delivery, payload filtering, template variables, YAML configuration, editor support, tests, and documentation.

Changes

Webhook Cue trigger

Layer / File(s) Summary
Webhook contracts and configuration
src/shared/cue/contracts.ts, src/main/cue/config/*, src/shared/cue-pipeline-types.ts, src/__tests__/main/cue/cue-yaml-loader.test.ts
Defines webhook configuration and path normalization, validates authentication and paths, and normalizes YAML subscriptions.
Shared webhook listener
src/main/cue/cue-webhook-server.ts, src/__tests__/main/cue/cue-webhook-server.test.ts
Adds a shared POST listener with secret or HMAC authentication, size limits, header redaction, fan-out, and lifecycle management.
Trigger dispatch and templates
src/main/cue/triggers/*, src/main/cue/cue-template-context-builder.ts, src/shared/templateVariables.ts, src/__tests__/main/cue/triggers/*
Registers webhook trigger sources, resolves secrets, applies filters, emits events, and exposes webhook metadata and payload variables.
Editor configuration round trip
src/renderer/components/CuePipelineEditor/*, src/shared/cue-pipeline-types.ts, src/__tests__/renderer/*
Adds the Webhook trigger option, configuration fields, validation, graph summaries, YAML serialization, YAML loading, icons, prompts, and colors.
Labels and documentation
docs/maestro-cue-events.md, src/renderer/components/CueHelpModal.tsx, src/renderer/constants/cuePatterns.ts, src/main/cue/stats/cue-stats-query.ts
Documents webhook.received and adds its human-readable labels and example pattern.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ExternalService
  participant CueWebhookServer
  participant CueWebhookTriggerSource
  participant CuePipeline
  ExternalService->>CueWebhookServer: POST authenticated webhook payload
  CueWebhookServer->>CueWebhookTriggerSource: Route and deliver sanitized payload
  CueWebhookTriggerSource->>CuePipeline: Apply filter and emit webhook.received
Loading

Possibly related PRs

Suggested labels: approved, ready to merge

Suggested reviewers: chr1syy

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 69.23% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding a generic webhook trigger for external events.
Linked Issues check ✅ Passed The changes implement generic webhook support end-to-end, matching issue #858’s request for external events to trigger Cue pipelines.
Out of Scope Changes check ✅ Passed The added documentation, tests, UI updates, and shared plumbing all support the webhook feature and do not appear unrelated.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/858-cue-webhook-trigger

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jul 25, 2026

Copy link
Copy Markdown

Greptile Summary

Adds authenticated generic webhook triggers to Cue.

  • Introduces a shared, reference-counted HTTP listener with direct-secret and HMAC authentication.
  • Wires webhook payloads through filtering, template variables, trigger registration, stats, and Cue contracts.
  • Adds visual editor configuration and YAML round-trip support.
  • Documents webhook setup and adds listener, trigger, validation, and editor tests.

Confidence Score: 3/5

The PR should not merge until webhook editor round-tripping and exact-byte HMAC verification are fixed.

Distinct webhook configurations can be silently consolidated when a pipeline is opened and saved, and valid signed binary deliveries are rejected because authentication hashes decoded text rather than the transmitted bytes.

Files Needing Attention: src/renderer/components/CuePipelineEditor/utils/yamlToPipeline.ts, src/main/cue/cue-webhook-server.ts

Important Files Changed

Filename Overview
src/main/cue/cue-webhook-server.ts Adds the shared authenticated listener, but raw-byte HMAC verification and malformed URL handling need correction.
src/main/cue/triggers/cue-webhook-trigger-source.ts Resolves secrets, registers listener routes, filters deliveries, and emits webhook events with appropriate lifecycle guards.
src/renderer/components/CuePipelineEditor/utils/yamlToPipeline.ts Hydrates webhook settings, but its grouping key merges triggers that have different webhook configurations.
src/renderer/components/CuePipelineEditor/utils/pipelineToYaml.ts Serializes webhook configuration correctly for one visual trigger, which exposes the grouping loss during round-trip.
src/main/cue/config/cue-config-validator.ts Requires authenticated webhook configuration and validates field shapes, exclusivity, and normalized paths.

Sequence Diagram

sequenceDiagram
  participant Sender
  participant Listener as Cue Webhook Listener
  participant Trigger as Webhook Trigger Source
  participant Filter as Cue Filter
  participant Engine as Cue Engine
  participant Agent
  Sender->>Listener: POST /cue/path
  Listener->>Listener: Enforce size and authenticate
  Listener->>Trigger: Sanitized delivery
  Trigger->>Filter: webhook.received event
  alt Filter matches and Cue enabled
    Filter->>Engine: Emit event
    Engine->>Agent: Render and execute prompt
  else Filter rejects
    Filter-->>Trigger: Drop event
  end
  Listener-->>Sender: 202 accepted
Loading

Comments Outside Diff (1)

  1. src/renderer/components/CuePipelineEditor/utils/yamlToPipeline.ts, line 293-305 (link)

    P1 Webhook configurations merge on round-trip

    When two webhook subscriptions in the same pipeline have matching filters but different paths, secrets, or signature headers, this key groups them into one visual trigger. Saving then applies the first subscription's webhook configuration to every branch, overwriting the other endpoint configuration and causing deliveries to route or authenticate incorrectly.

    Knowledge Base Used: Cue automation engine

Reviews (1): Last reviewed commit: "feat(cue): add generic webhook trigger f..." | Re-trigger Greptile

Comment thread src/main/cue/cue-webhook-server.ts Outdated
chunks.push(chunk);
});
req.on('end', () => {
if (!aborted) resolve(Buffer.concat(chunks).toString('utf8'));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 HMAC hashes decoded request text

When a signed webhook body contains bytes that are not valid UTF-8, this conversion replaces those bytes before authentication. Maestro therefore hashes different data than the sender signed and rejects the valid delivery with HTTP 401; retain the original Buffer for HMAC verification and decode a separate copy for payload handling.

Knowledge Base Used: Cue automation engine

Comment thread src/main/cue/cue-webhook-server.ts Outdated
respond(res, 404, { error: 'Unknown webhook path' });
return;
}
const path = normalizeWebhookPath(decodeURIComponent(match[1]));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Malformed paths become internal errors

A request path such as /cue/% or /cue/%GG makes decodeURIComponent throw. The outer handler converts this client-controlled routing error into an HTTP 500 and reports it as an application exception instead of returning a client error, adding avoidable error-tracker noise.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
src/main/cue/cue-webhook-server.ts (1)

111-122: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Consider a startup warning when binding beyond loopback.

getCueWebhookHost() lets MAESTRO_CUE_WEBHOOK_HOST widen the bind address, but nothing logs when it does - the risk is only documented in a comment. A stray 0.0.0.0 (or LAN IP) silently exposes an agent-triggering HTTP endpoint beyond the machine. A one-line onLog('warn', ...) in ensureServerStarted when the resolved host isn't loopback would give operators visibility into this footgun at effectively no cost.

Also applies to: 322-355

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/cue/cue-webhook-server.ts` around lines 111 - 122, Update
ensureServerStarted to emit a single onLog('warn', ...) startup warning when the
resolved host from getCueWebhookHost is not loopback, including that the webhook
endpoint is exposed beyond the local machine. Keep loopback bindings silent and
preserve the existing server startup behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/cue/cue-webhook-server.ts`:
- Around line 214-319: The readBody function currently collapses payload-size
overruns and stream errors into the same null result, causing
handleCueWebhookRequest to return 413 for connection failures. Change readBody
to return a result that distinguishes the too-large case from stream errors,
then update handleCueWebhookRequest to send 413 only for size-limit violations
and handle generic read failures with an appropriate non-413 response.

In `@src/renderer/components/CuePipelineEditor/utils/pipelineGraph.ts`:
- Around line 63-64: Update the webhook.received branch in the pipeline graph
summary to pass config.webhook_path through the existing normalizeWebhookPath
fallback, matching TriggerConfig behavior while preserving /cue/ for an unset
path.

In `@src/renderer/components/CuePipelineEditor/utils/pipelineToYaml.ts`:
- Around line 195-214: Treat whitespace-only webhook_secret_env values as unset
in the webhook.received serialization branch. Update the condition selecting
webhook.secret_env so it requires non-whitespace content, allowing a valid
webhook_secret to be emitted through the fallback path; preserve the existing
precedence for meaningful environment values.

---

Nitpick comments:
In `@src/main/cue/cue-webhook-server.ts`:
- Around line 111-122: Update ensureServerStarted to emit a single onLog('warn',
...) startup warning when the resolved host from getCueWebhookHost is not
loopback, including that the webhook endpoint is exposed beyond the local
machine. Keep loopback bindings silent and preserve the existing server startup
behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: c17cc779-06f3-4d17-bf98-965aa0250543

📥 Commits

Reviewing files that changed from the base of the PR and between 81e145f and ea23c2c.

📒 Files selected for processing (27)
  • docs/maestro-cue-events.md
  • src/__tests__/main/cue/cue-webhook-server.test.ts
  • src/__tests__/main/cue/cue-yaml-loader.test.ts
  • src/__tests__/main/cue/triggers/cue-webhook-trigger-source.test.ts
  • src/__tests__/renderer/components/CuePipelineEditor/drawers/TriggerDrawer.test.tsx
  • src/__tests__/renderer/components/CuePipelineEditor/utils/pipelineValidation.test.ts
  • src/__tests__/renderer/hooks/cue/usePipelineState.test.ts
  • src/main/cue/config/cue-config-normalizer.ts
  • src/main/cue/config/cue-config-validator.ts
  • src/main/cue/cue-template-context-builder.ts
  • src/main/cue/cue-webhook-server.ts
  • src/main/cue/stats/cue-stats-query.ts
  • src/main/cue/triggers/cue-trigger-source-registry.ts
  • src/main/cue/triggers/cue-webhook-trigger-source.ts
  • src/renderer/components/CueHelpModal.tsx
  • src/renderer/components/CuePipelineEditor/cueEventConstants.ts
  • src/renderer/components/CuePipelineEditor/drawers/TriggerDrawer.tsx
  • src/renderer/components/CuePipelineEditor/panels/triggers/TriggerConfig.tsx
  • src/renderer/components/CuePipelineEditor/utils/pipelineGraph.ts
  • src/renderer/components/CuePipelineEditor/utils/pipelineToYaml.ts
  • src/renderer/components/CuePipelineEditor/utils/pipelineValidation.ts
  • src/renderer/components/CuePipelineEditor/utils/yamlToPipeline.ts
  • src/renderer/constants/cuePatterns.ts
  • src/shared/cue-pipeline-types.ts
  • src/shared/cue/contracts.ts
  • src/shared/cue/cue-summary.ts
  • src/shared/templateVariables.ts

Comment thread src/main/cue/cue-webhook-server.ts
Comment thread src/renderer/components/CuePipelineEditor/utils/pipelineGraph.ts Outdated
Comment on lines +195 to +214
case 'webhook.received': {
// `secret` and `secret_env` are mutually exclusive in the schema, so
// emit the literal only when the trigger has no env var - that's the
// hand-written-YAML case we're preserving rather than encouraging.
const webhook: CueSubscription['webhook'] = {};
if (triggerData.config.webhook_path) webhook.path = triggerData.config.webhook_path;
if (triggerData.config.webhook_secret_env) {
webhook.secret_env = triggerData.config.webhook_secret_env;
} else if (triggerData.config.webhook_secret) {
webhook.secret = triggerData.config.webhook_secret;
}
if (triggerData.config.webhook_signature_header) {
webhook.signature_header = triggerData.config.webhook_signature_header;
}
sub.webhook = webhook;
if (triggerData.config.filter) {
sub.filter = triggerData.config.filter;
}
break;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Treat whitespace-only secret_env values as unset.

If webhook_secret_env is whitespace and webhook_secret is valid, validation permits the literal secret, but this branch serializes the whitespace env value and drops the literal. The saved YAML then fails webhook authentication validation.

Proposed fix
-			if (triggerData.config.webhook_secret_env) {
-				webhook.secret_env = triggerData.config.webhook_secret_env;
+			const secretEnv = triggerData.config.webhook_secret_env?.trim();
+			if (secretEnv) {
+				webhook.secret_env = secretEnv;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
case 'webhook.received': {
// `secret` and `secret_env` are mutually exclusive in the schema, so
// emit the literal only when the trigger has no env var - that's the
// hand-written-YAML case we're preserving rather than encouraging.
const webhook: CueSubscription['webhook'] = {};
if (triggerData.config.webhook_path) webhook.path = triggerData.config.webhook_path;
if (triggerData.config.webhook_secret_env) {
webhook.secret_env = triggerData.config.webhook_secret_env;
} else if (triggerData.config.webhook_secret) {
webhook.secret = triggerData.config.webhook_secret;
}
if (triggerData.config.webhook_signature_header) {
webhook.signature_header = triggerData.config.webhook_signature_header;
}
sub.webhook = webhook;
if (triggerData.config.filter) {
sub.filter = triggerData.config.filter;
}
break;
}
case 'webhook.received': {
// `secret` and `secret_env` are mutually exclusive in the schema, so
// emit the literal only when the trigger has no env var - that's the
// hand-written-YAML case we're preserving rather than encouraging.
const webhook: CueSubscription['webhook'] = {};
if (triggerData.config.webhook_path) webhook.path = triggerData.config.webhook_path;
const secretEnv = triggerData.config.webhook_secret_env?.trim();
if (secretEnv) {
webhook.secret_env = secretEnv;
} else if (triggerData.config.webhook_secret) {
webhook.secret = triggerData.config.webhook_secret;
}
if (triggerData.config.webhook_signature_header) {
webhook.signature_header = triggerData.config.webhook_signature_header;
}
sub.webhook = webhook;
if (triggerData.config.filter) {
sub.filter = triggerData.config.filter;
}
break;
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/renderer/components/CuePipelineEditor/utils/pipelineToYaml.ts` around
lines 195 - 214, Treat whitespace-only webhook_secret_env values as unset in the
webhook.received serialization branch. Update the condition selecting
webhook.secret_env so it requires non-whitespace content, allowing a valid
webhook_secret to be emitted through the fallback path; preserve the existing
precedence for meaningful environment values.

- HMAC now covers the received bytes, not a decoded string. Senders sign the
  wire bytes, and round-tripping a non-UTF-8 body through toString('utf8')
  substitutes U+FFFD, which changed the digest and rejected legitimately
  signed deliveries. Body decoding moved after the signature check, and raw
  body truncation now slices the buffer so it can't cut mid-codepoint.

- Trigger group key includes the webhook block. Two webhook.received subs on
  different paths collapsed into one visual trigger on load, so the next
  editor save rewrote both to a single path and silently broke a live
  endpoint.

- readBody distinguishes a size overrun from a stream error: a dropped
  connection answered 413 "Payload too large", sending operators after a
  limit that was never hit. Stream errors now answer 400.

- A malformed percent-escape (/cue/%) made decodeURIComponent throw, which
  surfaced as a 500 and a Sentry report for what is a bad request. Now 404.

- Warn once at startup when MAESTRO_CUE_WEBHOOK_HOST binds past loopback.
  It's a supported choice, but a silent one is a footgun.

- Trigger node summary resolves an unset webhook path through the same
  name-slug fallback the config panel shows, instead of rendering a bare
  /cue/.

Adds regression coverage for each: raw-byte HMAC, malformed escape, stream
error vs size cap, and the two-path round trip.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/__tests__/renderer/components/CuePipelineEditor/utils/yamlToPipeline.test.ts`:
- Around line 1131-1133: Remove the duplicated triggers.map(...) expression in
the test assertion, leaving a single webhook_path mapping passed to
expect.arrayContaining. Ensure the resulting expect(...).toEqual(...) statement
remains syntactically valid.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: c31eeddc-6431-4939-a549-66f79bcaed8c

📥 Commits

Reviewing files that changed from the base of the PR and between ea23c2c and cd1c0a9.

📒 Files selected for processing (5)
  • src/__tests__/main/cue/cue-webhook-server.test.ts
  • src/__tests__/renderer/components/CuePipelineEditor/utils/yamlToPipeline.test.ts
  • src/main/cue/cue-webhook-server.ts
  • src/renderer/components/CuePipelineEditor/utils/pipelineGraph.ts
  • src/renderer/components/CuePipelineEditor/utils/yamlToPipeline.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/renderer/components/CuePipelineEditor/utils/pipelineGraph.ts
  • src/main/cue/cue-webhook-server.ts

Comment on lines +1131 to +1133
expect(
triggers.map((t) => (t.data as { config: { webhook_path?: string } }).config.webhook_path)
).toEqual(expect.arrayContaining(['from-github', 'from-ci']));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Remove the duplicated triggers.map(...) expression.

The supplied final snippet contains the same expression twice at Line 1132 without a separator. If both lines are checked in, the test will not compile. Keep only one expression.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/__tests__/renderer/components/CuePipelineEditor/utils/yamlToPipeline.test.ts`
around lines 1131 - 1133, Remove the duplicated triggers.map(...) expression in
the test assertion, leaving a single webhook_path mapping passed to
expect.arrayContaining. Ensure the resulting expect(...).toEqual(...) statement
remains syntactically valid.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant