Skip to content

fix(cue): enable multi-agent pipeline output passing and polish editor UX#572

Merged
reachraza merged 10 commits into0.16.0-RCfrom
cue-polish
Mar 14, 2026
Merged

fix(cue): enable multi-agent pipeline output passing and polish editor UX#572
reachraza merged 10 commits into0.16.0-RCfrom
cue-polish

Conversation

@reachraza
Copy link
Collaborator

@reachraza reachraza commented Mar 14, 2026

Summary

  • Fix core bug where upstream agent output never reached downstream agents in multi-agent pipelines — {{CUE_SOURCE_OUTPUT}} was missing from generated chain prompts
  • Add includeUpstreamOutput toggle, contextual placeholder, and placement hint to the agent config panel
  • Add outputTruncated boolean to completion event payloads (single-source and fan-in) so consumers know when output was clipped at 5K chars
  • Remove debug console.log from claude-output-parser.ts that was logging raw usage data in production
  • Mark Debate and Auto Run edge modes as "Coming Soon" since they have no backend implementation

Root Cause

pipelineToYaml.tsbuildChain() generated chain subscriptions with prompt: targetData.inputPrompt ?? '' — never injecting {{CUE_SOURCE_OUTPUT}}. The engine correctly populated sourceOutput in the event payload (visible in the activity dashboard), but the generated prompt never referenced it, so the downstream agent's prompt was blind to the upstream output.

Changes

Core fix (pipelineToYaml.ts)

  • Added ensureSourceOutputVariable() helper that auto-prepends {{CUE_SOURCE_OUTPUT}}\n\n unless the prompt already contains it (case-insensitive)
  • buildChain() now calls this helper, respecting the new includeUpstreamOutput toggle

UX improvements (NodeConfigPanel.tsx, CuePipelineEditor.tsx, cue-pipeline-types.ts)

  • Added includeUpstreamOutput?: boolean to AgentNodeData (default: true)
  • When an agent has incoming agent edges: updated placeholder text, added checkbox toggle, added {{CUE_SOURCE_OUTPUT}} placement hint
  • Computed hasIncomingAgentEdges in the editor and passed it through

Round-trip safety (yamlToPipeline.ts)

  • Strips auto-injected {{CUE_SOURCE_OUTPUT}}\n\n prefix when reconstructing pipeline from YAML to prevent accumulation on repeated save/load cycles

Engine refinements (cue-engine.ts, claude-output-parser.ts)

  • Added outputTruncated flag to single-source and fan-in completion event payloads
  • Added truncated field to FanInSourceCompletion interface
  • Removed debug console.log that was dumping raw usage JSON to stdout

Edge mode polish (EdgeConfigPanel.tsx)

  • Debate and Auto Run buttons now show "(Soon)" suffix, 50% opacity, pointer-events: none, and "Coming soon" tooltip

Test plan

  • 16 new unit tests across 4 test files (ensureSourceOutputVariable, includeUpstreamOutput toggle, prefix stripping, outputTruncated flag)
  • 3 new integration tests verifying end-to-end pipeline → YAML → template substitution
  • Full suite: 23,325 tests passing, 0 failures
  • TypeScript: npx tsc --noEmit clean (only pre-existing errors in unrelated file)
  • Manual: create trigger → agent1 → agent2 pipeline, save, verify {{CUE_SOURCE_OUTPUT}} in generated YAML
  • Manual: trigger the chain, confirm agent2 receives agent1's output in its prompt
  • Manual: toggle checkbox off, save, verify variable is removed from YAML
  • Manual: save/reopen pipeline editor, verify no prefix accumulation in prompt textarea

Summary by CodeRabbit

  • New Features

    • "Auto-include upstream output" toggle and improved prompt placeholders when an agent receives upstream data.
    • "Coming soon" indicators/disabled styling for unavailable edge modes.
    • Cmd+T now creates a new AI tab from any session mode.
    • File-watcher logging can be routed to a configurable log callback.
    • Subscription "label" is now supported.
  • Bug Fixes

    • Proper detection/propagation of truncated source outputs across completions and fan‑in.
    • Prevents auto‑injected upstream prefix from accumulating on prompt round‑trips.
    • Numeric filters safely handle non‑numeric inputs.
  • Tests

    • Expanded coverage for truncation, injection/substitution flows, YAML round‑trips, and validation.
  • Chores

    • Removed noisy debug logging from output parsing.

Pipeline-generated chain subscriptions were missing the {{CUE_SOURCE_OUTPUT}}
template variable, so upstream agent output never reached downstream agents.
Added ensureSourceOutputVariable() helper and applied it in buildChain().
Add includeUpstreamOutput toggle to agent nodes so users can opt out of
auto-injected {{CUE_SOURCE_OUTPUT}}. Update NodeConfigPanel with contextual
placeholder, checkbox, and placement hint when agent has incoming agent edges.
Strip auto-injected prefix in yamlToPipeline to prevent accumulation on
round-trip. 5 new tests covering toggle and prefix stripping.
Add outputTruncated boolean to both single-source and fan-in completion
event payloads so downstream consumers know when source output was clipped
at 5000 chars. Remove debug console.log from claude-output-parser that
was logging raw usage data to stdout in production.
Debate and autorun edge modes have no backend implementation yet.
Mark them as disabled with "(Soon)" label and tooltip to set correct
user expectations.
End-to-end tests verifying the full flow: pipelineToYamlSubscriptions
generates {{CUE_SOURCE_OUTPUT}} in chain prompts, and
substituteTemplateVariables resolves it to actual source output.
Covers normal, empty, and multi-content scenarios.
@coderabbitai
Copy link

coderabbitai bot commented Mar 14, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 408029f5-a588-451d-aa0b-e3845d8342b7

📥 Commits

Reviewing files that changed from the base of the PR and between c40a0e1 and ad7f771.

📒 Files selected for processing (5)
  • src/__tests__/main/cue/cue-filter.test.ts
  • src/__tests__/main/cue/cue-yaml-loader.test.ts
  • src/__tests__/renderer/hooks/useMainKeyboardHandler.test.ts
  • src/main/cue/cue-yaml-loader.ts
  • src/renderer/hooks/keyboard/useMainKeyboardHandler.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/tests/renderer/hooks/useMainKeyboardHandler.test.ts
  • src/tests/main/cue/cue-filter.test.ts

📝 Walkthrough

Walkthrough

Adds opt-in upstream-output injection/stripping via {{CUE_SOURCE_OUTPUT}} with ensureSourceOutputVariable and includeUpstreamOutput; UI controls for incoming-agent edges and auto-include; propagate outputTruncated through engine/fan-in and onLog hooks; tighten numeric filters and YAML validation; expand tests; enable Cmd+T to create AI tab.

Changes

Cohort / File(s) Summary
Engine & logging
src/main/cue/cue-engine.ts, src/main/cue/cue-file-watcher.ts
Compute and propagate per-source truncated/aggregate outputTruncated through single-source and fan-in complete/timeout paths; add/accept onLog callback and forward logs from watchers/subscribers.
Pipeline serialization & types
src/renderer/components/CuePipelineEditor/utils/pipelineToYaml.ts, src/renderer/components/CuePipelineEditor/utils/yamlToPipeline.ts, src/shared/cue-pipeline-types.ts
Add/export ensureSourceOutputVariable(prompt) and SOURCE_OUTPUT_VAR; conditionally inject {{CUE_SOURCE_OUTPUT}} into agent.completed prompts when includeUpstreamOutput is enabled; strip auto-injected prefix on import; add includeUpstreamOutput?: boolean to AgentNodeData.
UI & panels
src/renderer/components/CuePipelineEditor/CuePipelineEditor.tsx, .../panels/NodeConfigPanel.tsx, .../panels/EdgeConfigPanel.tsx
Detect hasIncomingAgentEdges, thread into NodeConfigPanel/AgentConfig, add "Auto-include upstream output" checkbox and placeholder/helper text; add comingSoon flag for some edge modes and render disabled behavior.
Filtering & YAML validation
src/main/cue/cue-filter.ts, src/main/cue/cue-yaml-loader.ts, src/main/cue/cue-types.ts
Introduce toComparableNumber to strictly coerce numeric operands and return false for invalid numeric comparisons; map optional label on subscriptions; enforce non-empty/unique subscription names and tighten schedule/interval bounds/validation messages.
Fan-in truncation handling
src/main/cue/cue-engine.ts
Record local rawOutput per source, compute truncated flag from stdout length, and include outputTruncated in fan-in completion and timeout continue payloads.
Parser
src/main/parsers/claude-output-parser.ts
Remove debug console.log when usage data present (no behavioral change).
Keyboard handler
src/renderer/hooks/keyboard/useMainKeyboardHandler.ts
Make Cmd+T create a new AI tab regardless of active session inputMode; update session replacement and autofocus logic.
Tests
src/__tests__/** (many files)
Add/expand tests covering: outputTruncated propagation and fan-in, ensureSourceOutputVariable behavior, includeUpstreamOutput injection/substitution and stripping, onLog forwarding, NaN handling in numeric filters, YAML label/validation, file-watcher onLog, and Cmd+T keyboard behavior.

Sequence Diagram

sequenceDiagram
    participant UpAgent as UpstreamAgent
    participant Engine as CUEEngine
    participant PtoY as pipelineToYaml
    participant Resolver as TemplateResolver
    participant DownAgent as DownstreamAgent
    participant YtoP as yamlToPipeline

    UpAgent->>Engine: emit completion(stdout)
    Engine->>Engine: compute output & truncated flag
    Engine->>PtoY: emit agent.completed subscription (includeUpstreamOutput?)
    PtoY->>PtoY: ensureSourceOutputVariable(prompt) when injecting
    PtoY->>Resolver: deliver subscription containing {{CUE_SOURCE_OUTPUT}}
    Resolver->>DownAgent: resolved prompt with injected upstream output
    DownAgent->>YtoP: persist/import pipeline
    YtoP->>YtoP: strip auto-injected "{{CUE_SOURCE_OUTPUT}}" prefix on import
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main changes: enabling multi-agent pipeline output passing via {{CUE_SOURCE_OUTPUT}} and polishing editor UX with toggles, placeholders, and coming-soon indicators.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch cue-polish
📝 Coding Plan
  • Generate coding plan for human review comments

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 and usage tips.

@reachraza
Copy link
Collaborator Author

@CodeRabbit review

@coderabbitai
Copy link

coderabbitai bot commented Mar 14, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@greptile-apps
Copy link

greptile-apps bot commented Mar 14, 2026

Greptile Summary

This PR fixes a core multi-agent pipeline bug where downstream agents never received upstream output because {{CUE_SOURCE_OUTPUT}} was never injected into generated chain prompts. It also adds the outputTruncated flag to completion event payloads, removes a debug console.log, and polishes the editor UX with a per-node toggle and "Coming Soon" markers for unimplemented edge modes. The changes are well-tested with 19 new unit/integration tests.

Three issues were found during review:

  • Round-trip data loss for includeUpstreamOutput: false (yamlToPipeline.ts): The stripping logic correctly removes the auto-injected prefix on YAML load, but never sets includeUpstreamOutput: false back on the reconstructed node when the prefix is absent. On the next save, pipelineToYaml.ts treats the undefined value as true and re-injects the prefix — silently overriding the user's opt-out. The checkbox in the UI will also appear checked on reload, giving false feedback.

  • outputTruncated missing in fan-in timeout continue path (cue-engine.ts): handleFanIn correctly emits outputTruncated: completions.some((c) => c.truncated), but handleFanInTimeout in continue mode fires with partial completions and omits the field entirely — breaking consistency for consumers that depend on it.

  • "Coming soon" tooltip suppressed by pointer-events: none (EdgeConfigPanel.tsx): Native browser tooltips require mouseover events; applying pointer-events: none to the button also prevents the title tooltip from appearing, making the hint invisible to users. The if (comingSoon) return; guard inside onClick also becomes dead code.

Confidence Score: 3/5

  • Safe to merge for the core bug fix, but has a round-trip data loss bug and a missing field in an edge-case code path that should be resolved first.
  • The primary fix (injecting {{CUE_SOURCE_OUTPUT}} into chain prompts) is correct and well-tested. However, includeUpstreamOutput: false is not round-tripped through YAML, meaning users who opt out will have their setting silently reverted on the next save. The missing outputTruncated in the fan-in timeout continuation path is a contract inconsistency. The tooltip issue is a UX regression on an otherwise cosmetic feature.
  • src/renderer/components/CuePipelineEditor/utils/yamlToPipeline.ts (round-trip bug) and src/main/cue/cue-engine.ts (missing field in timeout continuation path) need the most attention before merging.

Important Files Changed

Filename Overview
src/renderer/components/CuePipelineEditor/utils/pipelineToYaml.ts Adds ensureSourceOutputVariable() helper and wires includeUpstreamOutput toggle into buildChain(). Core fix is correct; ensureSourceOutputVariable is exported for testing and works as intended.
src/renderer/components/CuePipelineEditor/utils/yamlToPipeline.ts Strips the auto-injected {{CUE_SOURCE_OUTPUT}}\n\n prefix on YAML load to prevent accumulation, but does not restore the includeUpstreamOutput: false flag on agent nodes — causing a round-trip data loss bug for users who opted out.
src/main/cue/cue-engine.ts Adds outputTruncated to single-source and normal fan-in completion payloads; but the fan-in timeout continue path in handleFanInTimeout is missing the outputTruncated field.
src/renderer/components/CuePipelineEditor/panels/EdgeConfigPanel.tsx Marks Debate and Auto Run as "Coming Soon" with opacity, pointer-events: none, and a title tooltip — but the tooltip is invisible because pointer-events: none prevents the mouseover event that triggers it.
src/renderer/components/CuePipelineEditor/panels/NodeConfigPanel.tsx Adds hasIncomingAgentEdges prop, contextual placeholder text, checkbox toggle, and placement hint for the upstream output feature. Changes are clean and well-structured.

Sequence Diagram

sequenceDiagram
    participant UI as Pipeline Editor UI
    participant ToYaml as pipelineToYaml.ts
    participant YAML as cue.yaml
    participant Engine as CueEngine
    participant Agent1 as Upstream Agent
    participant Agent2 as Downstream Agent

    UI->>ToYaml: Save pipeline (includeUpstreamOutput=true)
    ToYaml->>ToYaml: ensureSourceOutputVariable(prompt)<br/>→ prepends {{CUE_SOURCE_OUTPUT}}
    ToYaml->>YAML: Write subscription with<br/>prompt: "{{CUE_SOURCE_OUTPUT}}\n\nUser prompt"

    Agent1-->>Engine: notifyAgentCompleted(stdout)
    Engine->>Engine: slice(-5000), set outputTruncated flag
    Engine->>Agent2: CueEvent { sourceOutput, outputTruncated }
    Engine->>Engine: substituteTemplateVariables<br/>{{CUE_SOURCE_OUTPUT}} → actual output
    Engine->>Agent2: Final prompt with upstream output injected

    UI->>ToYaml: Load YAML back (yamlToPipeline)
    ToYaml->>ToYaml: Strip "{{CUE_SOURCE_OUTPUT}}\n\n" prefix<br/>restore inputPrompt for display
    ToYaml->>UI: AgentNodeData { inputPrompt (stripped) }

    Note over UI,Agent2: ⚠ includeUpstreamOutput:false is NOT<br/>restored on load — setting is lost
    Note over Engine: ⚠ outputTruncated missing in<br/>fan-in timeout (continue) path
Loading

Comments Outside Diff (1)

  1. src/main/cue/cue-engine.ts, line 756-768 (link)

    outputTruncated missing in fan-in timeout continue path

    The normal fan-in completion path (line 712) correctly adds outputTruncated: completions.some((c) => c.truncated) to the event payload. However, handleFanInTimeout when timeout_on_fail === 'continue' fires with partial completions but omits outputTruncated entirely. Since FanInSourceCompletion now carries a truncated boolean, the data is already available in tracker.

    Consumers relying on outputTruncated (e.g., UI activity dashboard or downstream CUE subscriptions) will see undefined instead of true for timed-out fan-in events where some output was clipped.

    payload: {
        completedSessions: completions.map((c) => c.sessionId),
        timedOutSessions: timedOutSources,
        sourceSession: completions.map((c) => c.sessionName).join(', '),
        sourceOutput: completions.map((c) => c.output).join('\n---\n'),
        outputTruncated: completions.some((c) => c.truncated),
        partial: true,
    },

Last reviewed commit: 58b1050

Comment on lines 350 to +356
if (sub.prompt) {
(targetNode.data as AgentNodeData).inputPrompt = sub.prompt;
// Strip auto-injected {{CUE_SOURCE_OUTPUT}} prefix to prevent accumulation on round-trip
const AUTO_PREFIX = '{{CUE_SOURCE_OUTPUT}}\n\n';
const strippedPrompt = sub.prompt.startsWith(AUTO_PREFIX)
? sub.prompt.slice(AUTO_PREFIX.length)
: sub.prompt;
(targetNode.data as AgentNodeData).inputPrompt = strippedPrompt || undefined;
Copy link

Choose a reason for hiding this comment

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

includeUpstreamOutput: false lost on YAML round-trip

When a user toggles "Auto-include upstream output" off (includeUpstreamOutput: false), the generated YAML omits the {{CUE_SOURCE_OUTPUT}}\n\n prefix. However, when that YAML is loaded back, this code only strips the prefix if it's present — it never sets includeUpstreamOutput: false on the reconstructed node. The loaded node therefore has includeUpstreamOutput: undefined, which pipelineToYaml.ts treats as true (targetData.includeUpstreamOutput !== false is true for undefined).

Result: The user's opt-out is silently overridden on the next save — the prefix is auto-added back, and the checkbox in the UI shows "checked" even though the user had unchecked it.

The fix is to infer includeUpstreamOutput: false when the prompt for an agent.completed chain subscription does not contain {{CUE_SOURCE_OUTPUT}} at all:

if (sub.prompt) {
    const AUTO_PREFIX = '{{CUE_SOURCE_OUTPUT}}\n\n';
    const hasVariable = sub.prompt.toUpperCase().includes('{{CUE_SOURCE_OUTPUT}}');
    if (sub.prompt.startsWith(AUTO_PREFIX)) {
        const strippedPrompt = sub.prompt.slice(AUTO_PREFIX.length);
        (targetNode.data as AgentNodeData).inputPrompt = strippedPrompt || undefined;
        // includeUpstreamOutput stays undefined (treated as true) — correct
    } else if (!hasVariable) {
        // User explicitly placed no variable → they opted out
        (targetNode.data as AgentNodeData).inputPrompt = sub.prompt || undefined;
        (targetNode.data as AgentNodeData).includeUpstreamOutput = false;
    } else {
        // Variable is present but not as an auto-prefix (user-placed)
        (targetNode.data as AgentNodeData).inputPrompt = sub.prompt;
    }
}

Comment on lines +165 to 171
cursor: comingSoon ? 'default' : 'pointer',
transition: 'all 0.15s',
opacity: comingSoon ? 0.5 : 1,
pointerEvents: comingSoon ? 'none' : undefined,
}}
title={comingSoon ? 'Coming soon' : undefined}
>
Copy link

Choose a reason for hiding this comment

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

pointer-events: none suppresses the "Coming soon" tooltip

The title attribute tooltip is a native browser tooltip that requires the element to receive mouseover events. Setting pointerEvents: 'none' on the button prevents all pointer events from reaching it, so the tooltip defined on line 170 (title={comingSoon ? 'Coming soon' : undefined}) will never be shown to users.

Additionally, the if (comingSoon) return; guard in the onClick handler (line 147) is now dead code — the click can never fire when pointer-events: none is set.

To display the tooltip, move pointer-events: none to the inner content and keep the outer button as the event target, or wrap the button in a container that renders the tooltip:

style={{
    // ...
    cursor: comingSoon ? 'default' : 'pointer',
    opacity: comingSoon ? 0.5 : 1,
    // Remove: pointerEvents: comingSoon ? 'none' : undefined,
}}
onClick={() => {
    if (comingSoon) return; // keep this guard
    // ...
}}
title={comingSoon ? 'Coming soon' : undefined}

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/main/cue/cue-engine.ts`:
- Around line 712-713: The fan-in timeout/continue completion payloads omit the
outputTruncated flag, causing inconsistent downstream handling; update the
timeout and continue payload builders in cue-engine (the fan-in timeout/continue
branch near the fan-in completion logic where completions are collected and a
payload is created) to include outputTruncated: completions.some(c =>
c.truncated) (same expression used for the normal fan-in output), ensuring both
timeout and continue payloads propagate the same flag (modify the payload
objects constructed in the timeout and continue handlers so they include
outputTruncated).

In `@src/renderer/components/CuePipelineEditor/panels/EdgeConfigPanel.tsx`:
- Around line 165-170: The current style uses pointerEvents: 'none' when
comingSoon is true which prevents the title/tooltip from showing; in
EdgeConfigPanel.tsx remove pointerEvents: comingSoon ? 'none' : undefined from
the style and instead guard actions via the component's click handler (check the
comingSoon flag in the onClick handler of the button/element) or set a
disabled/aria-disabled state so the element still receives hover events for the
title/tooltip; keep cursor and opacity logic (cursor: comingSoon ? 'default' :
'pointer', opacity: comingSoon ? 0.5 : 1) and ensure title={comingSoon ? 'Coming
soon' : undefined} remains to show the tooltip.

In `@src/renderer/components/CuePipelineEditor/panels/NodeConfigPanel.tsx`:
- Around line 517-521: The placeholder text currently only checks
hasIncomingAgentEdges and therefore can claim "Upstream output is auto-included"
even when the node's includeUpstreamOutput is false; update the placeholder
logic in NodeConfigPanel to consider both hasIncomingAgentEdges and the node's
includeUpstreamOutput flag (the state/prop tied to the checkbox named
includeUpstreamOutput) so it only shows the "auto-included via
{{CUE_SOURCE_OUTPUT}}" message when hasIncomingAgentEdges === true AND
includeUpstreamOutput === true; locate the placeholder usage near the
input/textarea render in the NodeConfigPanel component and adjust the
conditional to reflect both symbols.

In `@src/renderer/components/CuePipelineEditor/utils/yamlToPipeline.ts`:
- Around line 351-356: The current logic only removes the auto-injected prefix
AUTO_PREFIX ('{{CUE_SOURCE_OUTPUT}}\n\n') so bare tokens like
'{{CUE_SOURCE_OUTPUT}}' remain; update the stripping in the yamlToPipeline
conversion (the block that computes AUTO_PREFIX, strippedPrompt and assigns
(targetNode.data as AgentNodeData).inputPrompt) to also detect and remove the
bare token variant (e.g., BARE_TOKEN = '{{CUE_SOURCE_OUTPUT}}') — handle cases
where sub.prompt equals the bare token or starts with the bare token followed by
optional newlines, then slice those characters out before assigning inputPrompt
(use the existing strippedPrompt variable logic to set undefined when empty).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 733e4d52-9a81-40aa-a6bf-eac2d54c4917

📥 Commits

Reviewing files that changed from the base of the PR and between 5c0d9d7 and 58b1050.

📒 Files selected for processing (12)
  • src/__tests__/main/cue/cue-completion-chains.test.ts
  • src/__tests__/renderer/components/CuePipelineEditor/utils/pipelineChainIntegration.test.ts
  • src/__tests__/renderer/components/CuePipelineEditor/utils/pipelineToYaml.test.ts
  • src/__tests__/renderer/components/CuePipelineEditor/utils/yamlToPipeline.test.ts
  • src/main/cue/cue-engine.ts
  • src/main/parsers/claude-output-parser.ts
  • src/renderer/components/CuePipelineEditor/CuePipelineEditor.tsx
  • src/renderer/components/CuePipelineEditor/panels/EdgeConfigPanel.tsx
  • src/renderer/components/CuePipelineEditor/panels/NodeConfigPanel.tsx
  • src/renderer/components/CuePipelineEditor/utils/pipelineToYaml.ts
  • src/renderer/components/CuePipelineEditor/utils/yamlToPipeline.ts
  • src/shared/cue-pipeline-types.ts
💤 Files with no reviewable changes (1)
  • src/main/parsers/claude-output-parser.ts

Comment on lines +712 to 713
outputTruncated: completions.some((c) => c.truncated),
},
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Propagate outputTruncated in fan-in timeout/continue payloads as well.

outputTruncated is now set for fan-in completion, but the timeout-continue completion payload (Line 762 onward) omits it. That makes downstream event handling inconsistent depending on timeout path.

Suggested fix
 			const event: CueEvent = {
 				id: crypto.randomUUID(),
 				type: 'agent.completed',
 				timestamp: new Date().toISOString(),
 				triggerName: sub.name,
 				payload: {
 					completedSessions: completions.map((c) => c.sessionId),
 					timedOutSessions: timedOutSources,
 					sourceSession: completions.map((c) => c.sessionName).join(', '),
 					sourceOutput: completions.map((c) => c.output).join('\n---\n'),
+					outputTruncated: completions.some((c) => c.truncated),
 					partial: true,
 				},
 			};
📝 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
outputTruncated: completions.some((c) => c.truncated),
},
const event: CueEvent = {
id: crypto.randomUUID(),
type: 'agent.completed',
timestamp: new Date().toISOString(),
triggerName: sub.name,
payload: {
completedSessions: completions.map((c) => c.sessionId),
timedOutSessions: timedOutSources,
sourceSession: completions.map((c) => c.sessionName).join(', '),
sourceOutput: completions.map((c) => c.output).join('\n---\n'),
outputTruncated: completions.some((c) => c.truncated),
partial: true,
},
};
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/cue/cue-engine.ts` around lines 712 - 713, The fan-in
timeout/continue completion payloads omit the outputTruncated flag, causing
inconsistent downstream handling; update the timeout and continue payload
builders in cue-engine (the fan-in timeout/continue branch near the fan-in
completion logic where completions are collected and a payload is created) to
include outputTruncated: completions.some(c => c.truncated) (same expression
used for the normal fan-in output), ensuring both timeout and continue payloads
propagate the same flag (modify the payload objects constructed in the timeout
and continue handlers so they include outputTruncated).

…e token stripping, timeout payload

- Remove pointerEvents: 'none' from coming-soon edge buttons so title
  tooltip still shows on hover (onClick guard already prevents action)
- Update NodeConfigPanel placeholder to check both hasIncomingAgentEdges
  AND includeUpstreamOutput before claiming output is auto-included
- Strip bare {{CUE_SOURCE_OUTPUT}} token (without trailing \n\n) in
  yamlToPipeline round-trip
- Add outputTruncated to fan-in timeout continue-mode payload for
  consistency with normal fan-in and single-source paths
@reachraza
Copy link
Collaborator Author

@CodeRabbit review

@coderabbitai
Copy link

coderabbitai bot commented Mar 14, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/__tests__/main/cue/cue-completion-chains.test.ts (1)

159-213: Add one exact-limit boundary test (5000 chars).

Nice above/below-limit coverage. Adding an exact-5000-char case would lock the intended > truncation semantics and guard against off-by-one regressions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/__tests__/main/cue/cue-completion-chains.test.ts` around lines 159 - 213,
Add a new unit test in the same suite that sends exactly 5000 characters to
CueEngine.notifyAgentCompleted and asserts the engine does not truncate:
createMockConfig/subscriptions as in the other tests, instantiate
CueEngine(deps), start it, call notifyAgentCompleted('agent-a', { stdout:
'x'.repeat(5000) }), then inspect the request from deps.onCueRun mock and assert
(event.payload.sourceOutput as string).length === 5000 and
event.payload.outputTruncated === false so the boundary behavior (">5000"
triggers truncation) is enforced; reference CueEngine.notifyAgentCompleted and
the deps.onCueRun mock to locate where to add the test.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/__tests__/main/cue/cue-completion-chains.test.ts`:
- Around line 159-213: Add a new unit test in the same suite that sends exactly
5000 characters to CueEngine.notifyAgentCompleted and asserts the engine does
not truncate: createMockConfig/subscriptions as in the other tests, instantiate
CueEngine(deps), start it, call notifyAgentCompleted('agent-a', { stdout:
'x'.repeat(5000) }), then inspect the request from deps.onCueRun mock and assert
(event.payload.sourceOutput as string).length === 5000 and
event.payload.outputTruncated === false so the boundary behavior (">5000"
triggers truncation) is enforced; reference CueEngine.notifyAgentCompleted and
the deps.onCueRun mock to locate where to add the test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 326de079-83c7-4796-b672-73889f35e936

📥 Commits

Reviewing files that changed from the base of the PR and between 58b1050 and 350c26c.

📒 Files selected for processing (6)
  • src/__tests__/main/cue/cue-completion-chains.test.ts
  • src/__tests__/renderer/components/CuePipelineEditor/utils/yamlToPipeline.test.ts
  • src/main/cue/cue-engine.ts
  • src/renderer/components/CuePipelineEditor/panels/EdgeConfigPanel.tsx
  • src/renderer/components/CuePipelineEditor/panels/NodeConfigPanel.tsx
  • src/renderer/components/CuePipelineEditor/utils/yamlToPipeline.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/tests/renderer/components/CuePipelineEditor/utils/yamlToPipeline.test.ts
  • src/main/cue/cue-engine.ts

…oduction readiness

Fix NaN bug in numeric filter comparisons where non-numeric payload
values silently passed through >=, <=, >, < filters. Route file watcher
errors through engine logger instead of console.error. Add validation
for duplicate/empty subscription names, HH:MM time ranges, interval
upper bounds, and label field parsing. 26 new tests (408 total).
@reachraza
Copy link
Collaborator Author

@CodeRabbit review

@coderabbitai
Copy link

coderabbitai bot commented Mar 14, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/main/cue/cue-file-watcher.ts (1)

19-19: Preserve error context in the watcher logging path.

At Line 74 and Line 76, only a formatted string is emitted. Consider passing the original error object through the callback/fallback so stack/context is not lost.

Proposed change
+import type { BaseLogLevel } from '../../shared/logger-types';

 export interface CueFileWatcherConfig {
 	watchGlob: string;
 	projectRoot: string;
 	debounceMs: number;
 	onEvent: (event: CueEvent) => void;
 	triggerName: string;
-	onLog?: (level: string, message: string) => void;
+	onLog?: (level: BaseLogLevel, message: string, data?: unknown) => void;
 }
@@
 	watcher.on('error', (error) => {
 		const message = `[CUE] File watcher error for "${triggerName}": ${error}`;
 		if (config.onLog) {
-			config.onLog('error', message);
+			config.onLog('error', message, error);
 		} else {
-			console.error(message);
+			console.error(message, error);
 		}
 	});

As per coding guidelines: "Use Sentry utilities for explicit reporting ... to report exceptions with context and notable events."

Also applies to: 72-77

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/cue/cue-file-watcher.ts` at line 19, The watcher currently emits
only a formatted string via the onLog callback (onLog?: (level: string, message:
string) => void) which drops the original Error context; change the onLog
signature to accept an optional Error (e.g., onLog?: (level: string, message:
string, err?: Error) => void), update the places in cue-file-watcher where
errors are reported (the watcher error/logging paths around the existing log
calls) to pass the original error object as the third argument, and ensure any
fallback logger/consumer (where onLog is invoked) forwards that Error to Sentry
or logs err.stack so the stack/context is preserved.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/main/cue/cue-filter.ts`:
- Around line 47-64: Numeric comparisons in cue-filter.ts are vulnerable because
Number('') and Number(null) coerce to 0; replace direct Number(...) + isNaN
checks with a strict helper (e.g., toComparableNumber) that first rejects
null/undefined/empty-string operands and then converts and validates via
Number.isFinite(); update each branch that uses Number(payloadValue) /
Number(filterValue.slice(...)) (the '>=' / '<=' / '>' / '<' handling) to call
toComparableNumber for both threshold and payload and return false if the helper
indicates an invalid operand before performing the numeric comparison.

In `@src/main/cue/cue-yaml-loader.ts`:
- Around line 254-260: The current validation for heartbeat intervals (using the
variables sub and prefix in cue-yaml-loader.ts) allows NaN because it only
checks typeof and bounds; update the guard inside the validation block that
currently reads `typeof sub.interval_minutes !== 'number' ||
sub.interval_minutes <= 0 || sub.interval_minutes > 10080` to also require the
value be finite by adding a Number.isFinite(sub.interval_minutes) check (negated
to preserve the existing error branch), so the condition rejects NaN and
Infinity before pushing the error message.

---

Nitpick comments:
In `@src/main/cue/cue-file-watcher.ts`:
- Line 19: The watcher currently emits only a formatted string via the onLog
callback (onLog?: (level: string, message: string) => void) which drops the
original Error context; change the onLog signature to accept an optional Error
(e.g., onLog?: (level: string, message: string, err?: Error) => void), update
the places in cue-file-watcher where errors are reported (the watcher
error/logging paths around the existing log calls) to pass the original error
object as the third argument, and ensure any fallback logger/consumer (where
onLog is invoked) forwards that Error to Sentry or logs err.stack so the
stack/context is preserved.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 08da562f-afca-480e-ab20-80dca81d8682

📥 Commits

Reviewing files that changed from the base of the PR and between 350c26c and a90cc70.

📒 Files selected for processing (7)
  • src/__tests__/main/cue/cue-file-watcher.test.ts
  • src/__tests__/main/cue/cue-filter.test.ts
  • src/__tests__/main/cue/cue-yaml-loader.test.ts
  • src/main/cue/cue-engine.ts
  • src/main/cue/cue-file-watcher.ts
  • src/main/cue/cue-filter.ts
  • src/main/cue/cue-yaml-loader.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/cue/cue-engine.ts

The inputMode === 'ai' guard on the newTab shortcut prevented Cmd+T
(Ctrl+T on Windows) from working when a terminal tab was focused.
Removed the guard so the shortcut works regardless of active mode.
… in validation

Replace Number()+isNaN() with a toComparableNumber() helper that rejects
null, empty/whitespace strings, NaN, and Infinity via Number.isFinite().
Fixes edge case where Number('') and Number(null) silently coerce to 0
and pass numeric filters. Add Number.isFinite() guard to interval_minutes
validation. 7 new tests (415 total).
@reachraza
Copy link
Collaborator Author

@CodeRabbit review

@coderabbitai
Copy link

coderabbitai bot commented Mar 14, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/renderer/hooks/keyboard/useMainKeyboardHandler.ts (1)

610-623: ⚠️ Potential issue | 🟠 Major

Cmd+T in terminal mode should also flip session inputMode to 'ai'.

At Line 612 and Line 618, the new tab session is applied as returned by createTab, but createTab (src/renderer/utils/tabHelpers.ts, Line 321-368) does not set inputMode. So in terminal mode, the AI tab can be created while the session remains in terminal mode.

💡 Suggested fix
 				if (ctx.isTabShortcut(e, 'newTab')) {
 					e.preventDefault();
 					const result = ctx.createTab(ctx.activeSession, {
 						saveToHistory: ctx.defaultSaveToHistory,
 						showThinking: ctx.defaultShowThinking,
 					});
 					if (result) {
 						ctx.setSessions((prev: Session[]) =>
-							prev.map((s: Session) => (s.id === ctx.activeSession!.id ? result.session : s))
+							prev.map((s: Session) =>
+								s.id === ctx.activeSession!.id
+									? {
+											...result.session,
+											inputMode: 'ai',
+									  }
+									: s
+							)
 						);
 						// Auto-focus the input so user can start typing immediately
 						ctx.setActiveFocus('main');
 						setTimeout(() => ctx.inputRef.current?.focus(), FOCUS_AFTER_RENDER_DELAY_MS);
 						trackShortcut('newTab');
 					}
 				}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/renderer/hooks/keyboard/useMainKeyboardHandler.ts` around lines 610 -
623, The new-tab keyboard handler uses ctx.createTab(...) and then updates
sessions via ctx.setSessions but does not ensure the new session's inputMode is
set to 'ai', so creating a tab while in terminal mode preserves terminal
inputMode; after receiving result from ctx.createTab in useMainKeyboardHandler
(the block that calls ctx.setSessions and trackShortcut('newTab')), ensure the
session inserted or replaced has inputMode: 'ai' — e.g., derive the session
object from result.session, set session.inputMode = 'ai' (or use a shallow copy
with inputMode:'ai') before calling ctx.setSessions / ctx.setActiveSession;
reference ctx.createTab, result.session, ctx.setSessions, and ctx.activeSession
when making this change.
🧹 Nitpick comments (2)
src/__tests__/renderer/hooks/useMainKeyboardHandler.test.ts (1)

1571-1608: Strengthen the terminal-mode Cmd+T test to validate full behavior, not just invocation.

Line 1607 only checks that createTab ran. This misses regressions in the actual UX path (setSessions, setActiveFocus('main'), delayed inputRef.focus()).

✅ Suggested test hardening
 		describe('tab shortcuts in terminal mode', () => {
 			it('Cmd+T creates a new AI tab even when in terminal mode', () => {
+				vi.useFakeTimers();
 				const { result } = renderHook(() => useMainKeyboardHandler());

 				const mockCreateTab = vi.fn().mockReturnValue({
 					session: { id: 'session-1', aiTabs: [], activeTabId: 'new-tab' },
 				});
 				const mockSetSessions = vi.fn();
+				const mockSetActiveFocus = vi.fn();
+				const mockFocus = vi.fn();

 				result.current.keyboardHandlerRef.current = createUnifiedTabContext({
 					isTabShortcut: (_e: KeyboardEvent, actionId: string) => actionId === 'newTab',
 					createTab: mockCreateTab,
 					setSessions: mockSetSessions,
-					setActiveFocus: vi.fn(),
-					inputRef: { current: { focus: vi.fn() } },
+					setActiveFocus: mockSetActiveFocus,
+					inputRef: { current: { focus: mockFocus } },
 					activeSession: {
 						id: 'session-1',
 						aiTabs: [{ id: 'ai-tab-1', name: 'AI Tab 1', logs: [] }],
 						activeTabId: 'ai-tab-1',
@@
 				// Cmd+T should work regardless of inputMode
 				expect(mockCreateTab).toHaveBeenCalled();
+				expect(mockSetSessions).toHaveBeenCalled();
+				expect(mockSetActiveFocus).toHaveBeenCalledWith('main');
+				vi.advanceTimersByTime(50);
+				expect(mockFocus).toHaveBeenCalled();
+				vi.useRealTimers();
 			});
 		});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/__tests__/renderer/hooks/useMainKeyboardHandler.test.ts` around lines
1571 - 1608, The test currently only asserts createTab was called; extend the
assertion to validate the full UX flow from useMainKeyboardHandler: ensure
mockSetSessions was called with the new session data returned by mockCreateTab
(verify the sessions include the new tab), verify the setActiveFocus mock was
called with 'main', and confirm the inputRef.current.focus mock was invoked (use
fake timers or advance timers if the focus is called after a setTimeout).
Reference the keyboardHandlerRef returned by useMainKeyboardHandler, and the
mocks mockCreateTab, mockSetSessions, setActiveFocus, and inputRef to locate
where to add these assertions and any timer handling.
src/__tests__/main/cue/cue-filter.test.ts (1)

179-244: Good test coverage for numeric edge cases.

The test suite comprehensively validates the new strict coercion behavior. One optional addition to consider:

🧪 Optional: Add test for -Infinity and NaN literals
 			it('rejects Infinity payload value with numeric filter', () => {
 				expect(matchesFilter({ size: Infinity }, { size: '>0' })).toBe(false);
 			});
+
+			it('rejects -Infinity payload value with numeric filter', () => {
+				expect(matchesFilter({ size: -Infinity }, { size: '<0' })).toBe(false);
+			});
+
+			it('rejects NaN payload value with numeric filter', () => {
+				expect(matchesFilter({ size: NaN }, { size: '>0' })).toBe(false);
+			});
+
+			it('rejects Infinity in filter threshold', () => {
+				expect(matchesFilter({ size: 100 }, { size: '>Infinity' })).toBe(false);
+			});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/__tests__/main/cue/cue-filter.test.ts` around lines 179 - 244, Add tests
to the "NaN handling in numeric comparisons" suite to cover -Infinity and NaN
literals: (1) assert matchesFilter({ size: -Infinity }, { size: '>0' }) returns
false, (2) assert matchesFilter({ size: NaN }, { size: '>0' }) returns false,
and (3) assert matchesFilter({ size: 100 }, { size: '>NaN' }) returns false
(i.e., reject NaN threshold); place these alongside the existing cases
referencing the matchesFilter function so the strict coercion behavior covers
-Infinity and NaN both as payload values and as thresholds.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/main/cue/cue-yaml-loader.ts`:
- Around line 234-240: The duplicate-check currently uses the raw sub.name so
names with surrounding whitespace slip past; in the validation block around
seenNames, normalize the name by computing a trimmed string (e.g., const
normalized = String(sub.name).trim()) and use that normalized value for the
empty-string check, duplicate check against seenNames, and for adding to
seenNames; keep the original error messages using prefix but reference
normalized when testing/adding to seenNames and when interpolating the duplicate
name.

---

Outside diff comments:
In `@src/renderer/hooks/keyboard/useMainKeyboardHandler.ts`:
- Around line 610-623: The new-tab keyboard handler uses ctx.createTab(...) and
then updates sessions via ctx.setSessions but does not ensure the new session's
inputMode is set to 'ai', so creating a tab while in terminal mode preserves
terminal inputMode; after receiving result from ctx.createTab in
useMainKeyboardHandler (the block that calls ctx.setSessions and
trackShortcut('newTab')), ensure the session inserted or replaced has inputMode:
'ai' — e.g., derive the session object from result.session, set
session.inputMode = 'ai' (or use a shallow copy with inputMode:'ai') before
calling ctx.setSessions / ctx.setActiveSession; reference ctx.createTab,
result.session, ctx.setSessions, and ctx.activeSession when making this change.

---

Nitpick comments:
In `@src/__tests__/main/cue/cue-filter.test.ts`:
- Around line 179-244: Add tests to the "NaN handling in numeric comparisons"
suite to cover -Infinity and NaN literals: (1) assert matchesFilter({ size:
-Infinity }, { size: '>0' }) returns false, (2) assert matchesFilter({ size: NaN
}, { size: '>0' }) returns false, and (3) assert matchesFilter({ size: 100 }, {
size: '>NaN' }) returns false (i.e., reject NaN threshold); place these
alongside the existing cases referencing the matchesFilter function so the
strict coercion behavior covers -Infinity and NaN both as payload values and as
thresholds.

In `@src/__tests__/renderer/hooks/useMainKeyboardHandler.test.ts`:
- Around line 1571-1608: The test currently only asserts createTab was called;
extend the assertion to validate the full UX flow from useMainKeyboardHandler:
ensure mockSetSessions was called with the new session data returned by
mockCreateTab (verify the sessions include the new tab), verify the
setActiveFocus mock was called with 'main', and confirm the
inputRef.current.focus mock was invoked (use fake timers or advance timers if
the focus is called after a setTimeout). Reference the keyboardHandlerRef
returned by useMainKeyboardHandler, and the mocks mockCreateTab,
mockSetSessions, setActiveFocus, and inputRef to locate where to add these
assertions and any timer handling.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ceb7c444-1667-4588-a377-8b57fbf4d02e

📥 Commits

Reviewing files that changed from the base of the PR and between a90cc70 and c40a0e1.

📒 Files selected for processing (6)
  • src/__tests__/main/cue/cue-filter.test.ts
  • src/__tests__/main/cue/cue-yaml-loader.test.ts
  • src/__tests__/renderer/hooks/useMainKeyboardHandler.test.ts
  • src/main/cue/cue-filter.ts
  • src/main/cue/cue-yaml-loader.ts
  • src/renderer/hooks/keyboard/useMainKeyboardHandler.ts

…n new tab

Trim-normalize subscription names before duplicate detection so names
with surrounding whitespace are correctly caught. Ensure Cmd+T sets
inputMode to 'ai' so creating a tab from terminal mode switches to AI
view. Add -Infinity/NaN edge case tests for filter coercion.
@reachraza
Copy link
Collaborator Author

@CodeRabbit review

@coderabbitai
Copy link

coderabbitai bot commented Mar 14, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@reachraza reachraza merged commit cc7aec8 into 0.16.0-RC Mar 14, 2026
4 checks passed
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